環境構築からWEBアプリ開発・スマホアプリ開発まで。ときには動画制作やゲームも。

supilog
すぴろぐ

【ルービックキューブのタイマーを作る】第4回 スクランブル情報をAPI化する回

【ルービックキューブのタイマーを作る】第4回 スクランブル情報をAPI化する回

今回はスクランブル情報をAPI経由で取得できるようにしてみる。

API化について

LaravelのAPI化は難しくない。今回の場合は、認証なども無くてよいので、さらに簡単である。Controllerを用意して、返却したいデータ配列をreturnしてあげれば、あら不思議。

下記に、簡単な例を示す。

app/Http/Controllers/CubesApiController.php

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class CubesApiController extends Controller
{
public function scramble(): array
{
$ret = [
'a' => 'hogehoge',
'b' => 100
];
return $ret;
}
}
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class CubesApiController extends Controller { public function scramble(): array { $ret = [ 'a' => 'hogehoge', 'b' => 100 ]; return $ret; } }
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class CubesApiController extends Controller
{
    public function scramble(): array
    {
        $ret = [
            'a' => 'hogehoge',
            'b' => 100
        ];
        return $ret;
    }
}

routes/api.php

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?php
use App\Http\Controllers\CubesApiController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::get('/scramble', [CubesApiController::class, 'scramble'])->name('api.scramble');
<?php use App\Http\Controllers\CubesApiController; use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; Route::get('/scramble', [CubesApiController::class, 'scramble'])->name('api.scramble');
<?php

use App\Http\Controllers\CubesApiController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

Route::get('/scramble', [CubesApiController::class, 'scramble'])->name('api.scramble');

ブラウザでアクセスしてみる

ブラウザで「/api/scramble」にアクセスしてみる。

JSONが返却されました。あとはデータを生成して返却してあげれば立派なAPIだ。

仕様

GET /api/scramble

主にページロード時にスクランブル情報を取得するのに使用。スクランブル文字列、スクランブルカラー情報を保有する。

POST /api/store

タイマーストップ時に、データを保管する目的で使用する(予定)。この返却値に、次回用のスクランブル文字列、スクランブルカラー情報を保有する。※データ保管方法はこのあと考えるので、「/api/store」は作成しないかも。

実装

今回は、「GET /api/scramble」のAPIを作成して、その情報を元にスクランブルテキストを表示させるように修正する。

app/Http/Controllers/CubesApiController.php

スクランブルテキスト情報をAPI返却値に含める。カラー情報は未実装。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?php
namespace App\Http\Controllers;
use App\Services\CubeService;
class CubesApiController extends Controller
{
/**
* [API] スクランブル情報を取得
* @param CubeService $cs
* @return array[]
* @throws \Random\RandomException
*/
public function scramble(CubeService $cs): array
{
$scramble_text = implode(' ', $cs->scrambleToTextArray($cs->scramble()));
$scramble_colors = array();
return [
'scramble' => [
'text' => $scramble_text,
'colors' => $scramble_colors
]
];
}
}
<?php namespace App\Http\Controllers; use App\Services\CubeService; class CubesApiController extends Controller { /** * [API] スクランブル情報を取得 * @param CubeService $cs * @return array[] * @throws \Random\RandomException */ public function scramble(CubeService $cs): array { $scramble_text = implode(' ', $cs->scrambleToTextArray($cs->scramble())); $scramble_colors = array(); return [ 'scramble' => [ 'text' => $scramble_text, 'colors' => $scramble_colors ] ]; } }
<?php

namespace App\Http\Controllers;

use App\Services\CubeService;

class CubesApiController extends Controller
{
    /**
     * [API] スクランブル情報を取得
     * @param CubeService $cs
     * @return array[]
     * @throws \Random\RandomException
     */
    public function scramble(CubeService $cs): array
    {
        $scramble_text = implode(' ', $cs->scrambleToTextArray($cs->scramble()));
        $scramble_colors = array();
        return [
            'scramble' => [
                'text' => $scramble_text,
                'colors' => $scramble_colors
            ]
        ];
    }
}

resources/views/index.blade.php

一旦、HTMLを空にしておく。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<div id="scramble" class="sm:flex sm:justify-center text-4xl">&nbsp;</div>
<div id="scramble" class="sm:flex sm:justify-center text-4xl">&nbsp;</div>
<div id="scramble" class="sm:flex sm:justify-center text-4xl">&nbsp;</div>

resources/js/timer.js

ここからはJSでスクランブルを表示する。第2回で作成したtimer.jsのinit処理でスクランブル情報の表示処理を記述してみる。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
init: function () {
this.currentStatus = this.status.neutral;
window.addEventListener('keydown', (event) => {
this.keyDown(event);
});
window.addEventListener('keyup', (event) => {
this.keyUp(event);
});
// スクランブル情報の取得
this.scramble();
},
... 略 ...
scramble: function () {
var xhr = new XMLHttpRequest();
xhr.open('GET', '/api/scramble');
xhr.send();
xhr.onreadystatechange = () => {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
const json = JSON.parse(xhr.responseText);
document.getElementById('scramble').textContent = json.scramble.text;
}
}
}
}
init: function () { this.currentStatus = this.status.neutral; window.addEventListener('keydown', (event) => { this.keyDown(event); }); window.addEventListener('keyup', (event) => { this.keyUp(event); }); // スクランブル情報の取得 this.scramble(); }, ... 略 ... scramble: function () { var xhr = new XMLHttpRequest(); xhr.open('GET', '/api/scramble'); xhr.send(); xhr.onreadystatechange = () => { if (xhr.readyState === XMLHttpRequest.DONE) { if (xhr.status === 200) { const json = JSON.parse(xhr.responseText); document.getElementById('scramble').textContent = json.scramble.text; } } } }
    init: function () {
        this.currentStatus = this.status.neutral;
        window.addEventListener('keydown', (event) => {
            this.keyDown(event);
        });
        window.addEventListener('keyup', (event) => {
            this.keyUp(event);
        });
        // スクランブル情報の取得
        this.scramble();
    },

... 略 ...

    scramble: function () {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', '/api/scramble');
        xhr.send();
        xhr.onreadystatechange = () => {
            if (xhr.readyState === XMLHttpRequest.DONE) {
                if (xhr.status === 200) {
                    const json = JSON.parse(xhr.responseText);
                    document.getElementById('scramble').textContent = json.scramble.text;
                }
            }
        }
    }

確認してみる

何回かリロードしてみる。ちゃんと更新されているのが分かる。無事にAPI経由で表示されている。

↓リロードしてますw

まとめ

無事にAPI化出来ました。次回は、ルービックキューブの展開図のカラーリング対応か、データ保存処理か、どちらにしようかまだ迷ってますw それではまた次回お会いしましょう。

今回のソースコード

本日の実装が完了した状態のタグが「v1.0.4」です。

https://github.com/supilog/cube/tree/v1.0.4

  • app/Http/Controllers/CubesController.php
  • app/Http/Controllers/CubesApiController.php
  • resources/js/timer.js
  • resources/views/index.blade.php
  • routes/api.php

リンク

「ルービックキューブのタイマーを作る」シリーズ