inb4: salin tempel dari dokumentasi
Panduan ini berfokus pada penyebaran cepat set minimal untuk pengembangan API penuh sesuai dengan praktik terbaik, yang diambil dari dokumentasi Laravel 5.7, yang dikumpulkan di satu tempat. Saya menulis untuk diri sendiri dan kolega saya sebagai lembar contekan, saya harap ini akan bermanfaat bagi orang lain.
Preset
Kami menempatkan kerangka kerja
composer create-project --prefer-dist laravel/laravel scaffold-api
Hapus komponen UI yang tidak perlu (vuejs, reaksi)
php artisan preset none
Konfigurasikan koneksi basis data
Buka folder, edit file .env:
DB_CONNECTION=mysql DB_HOST=localhost DB_PORT=3306 DB_DATABASE=api-authentification DB_USERNAME=root DB_PASSWORD=
Memulai menghasilkan
Kami mengeksekusi di konsol
php artisan make:model Game -mrc
Kami mendapatkan model, migrasi, dan pengontrol:
Model created successfully. Factory created successfully. Created Migration: 2019_02_27_105610_create_games_table Controller created successfully.
Buat kolom di tabel database
Kami memperbaiki migrasi dengan menambahkan kolom ke tabel. Jenis yang paling umum digunakan:
increments('id')
string('title')
text('description')
tinyInteger('complexity')
boolean('isActive')
softDeletes()
Untuk bidang opsional, jangan lupa untuk menambahkan nilai default dengan ->default()
Terapkan migrasi dengan menjalankan php artisan migrate
Kami menghasilkan aturan validasi
Menjalankan php artisan make:request GameRequest
Buka App/Http/Requests/GameRequest.php
.
Dalam metode authorize()
, atur return true
hingga kami menambahkan otorisasi.
Array yang dikembalikan dalam metode rules()
menjelaskan aturan untuk semua kolom yang kami cantumkan dalam migrasi. Aturan yang tersedia di sini
Untuk meminimalkan kode, kami menggunakan saklar konstruksi untuk kata kerja http yang berbeda, alih-alih melakukan StoreGameRequest yang terpisah, UpdateGameRequest, dll.
public function rules(Request $request) { $rules = [ 'title' => 'required|string|unique:games,title', 'description' => '', 'complexity' => 'required|min:1|max:10', 'minPlayers' => 'required|min:1|max:10', 'maxPlayers' => 'required|min:1|max:10', 'isActive' => 'required|boolean' ]; switch ($this->getMethod()) { case 'POST': return $rules; case 'PUT': return [ 'game_id' => 'required|integer|exists:games,id', // . : unique:games,id,' . $this->route('game'), 'title' => [ 'required', Rule::unique('games')->ignore($this->title, 'title') // , ] ] + $rules; // // case 'PATCH': case 'DELETE': return [ 'game_id' => 'required|integer|exists:games,id' ]; } }
Opsi deskripsi kesalahan khusus
Jika Anda membutuhkan teks kesalahan Anda sendiri, kami mendefinisikan kembali metode messages (), yang mengembalikan array dengan terjemahan dari setiap aturan:
public function messages() { return [ 'date.required' => 'A date is required', 'date.date_format' => 'A date must be in format: Ym-d', 'date.unique' => 'This date is already taken', 'date.after_or_equal' => 'A date must be after or equal today', 'date.exists' => 'This date doesn\'t exists', ]; }
Untuk memastikan bahwa tidak hanya parameter yang diteruskan dalam badan permintaan, tetapi juga parameter yang dikirimkan dalam URL tersedia dalam aturan validasi, kami mendefinisikan kembali semua metode (yang biasanya digunakan dalam pengontrol dalam bentuk $ request-> semua ()):
public function all($keys = null) { // return $this->all(); $data = parent::all($keys); switch ($this->getMethod()) { // case 'PUT': // case 'PATCH': case 'DELETE': $data['date'] = $this->route('day'); } return $data; }
Kami mengonfigurasikan pengontrol dan mendeskripsikan logika bisnis
Buka Http\Controllers\GameController
. Kami menghapus metode yang dibuat create(), edit()
dimaksudkan untuk rendering form (karena kami memiliki REST API, mereka tidak diperlukan).
Ganti penggunaan standar use Illuminate\Http\Request;
, pada use App\Http\Requests\GameRequest;
kami use App\Http\Requests\GameRequest;
Selanjutnya, edit metode:
public function index() { return Game::all(); }
public function store(GameRequest $request) { $day = Game::create($request->validated()); return $day; }
public function show(Game $game) { return $game = Game::findOrFail($game); }
public function update(GameRequest $request, $id) { $game = Game::findOrFail($id); $game->fill($request->except(['game_id'])); $game->save(); return response()->json($game); }
public function destroy(GameRequest $request, $id) { $game = Game::findOrFail($id); if($game->delete()) return response(null, 204); }
Jika ada banyak logika, maka lebih baik untuk menempatkannya di Layanan / Repositori lapisan terpisah
Kustomisasi model
Buka model app / Http / Game.php dan tambahkan properti:
protected $fillable = ['title', 'description', 'complexity', 'minPlayers', 'maxPlayers', 'isActive']; protected $hidden = ['created_at', 'updated_at', 'deleted_at'];
Konfigurasikan middleware
Agar aplikasi kami selalu mengembalikan json terlepas dari header yang diteruskan, kami membuat middleware:
php artisan make:middleware ForceJsonResponse
dan tambahkan kode ke dalamnya:
public function handle($request, Closure $next) { $request->headers->set('Accept', 'application/json'); return $next($request); }
Daftarkan middleware ini di app/Http/Kernel.php
:
... 'api' => [ 'throttle:60,1', 'bindings', \App\Http\Middleware\ForceJsonResponse::class, ],
Kami mengonfigurasi perutean
Buka routes/api.php
dan tambahkan:
use Http\Controllers\GameController; Route::apiResource('/games', 'GameController');
Rute statis :: metode apiResource, tidak seperti metode sumber daya, mengecualikan metode edit dan membuat, hanya menyisakan indeks, menunjukkan, menyimpan, memperbarui, menghancurkan.
Hal yang sama dapat dicapai dengan catatan yang lebih jelas:
Route::resource('/games', 'GameController')->only([ 'index', 'show', 'store', 'update', 'destroy' ]);
Sekarang, Anda dapat melihat lintasan dengan php artisan route:list
command dan menggunakannya.
REST API sudah siap!
Kata penutupKata penutup
Jika Anda memerlukan otorisasi, maka Paspor Laravel standar akan melakukannya.
Konfigurasikan otorisasi Paspor Laravel
composer require laravel/passport php artisan make:auth php artisan passport:install php artisan migrate
Tambahkan sifat Laravel\Passport\HasApiTokens
ke App\User
Model App\User
dan panggil Passport::routesmethod
di app/AuthServiceProvider
boot
app/AuthServiceProvider
:
public function boot() { $this->registerPolicies(); Passport::routes(); }
Dalam file config/auth.php
ubah driver ke paspor:
'api' => [ 'driver' => 'passport', 'provider' => 'users', ],
Buat controller untuk otorisasi 'php artisan make: controller Api / AuthController.php`
Tambahkan kode di sana
use App\User; use Illuminate\Support\Facades\Validator;
public function register (Request $request) { $validator = Validator::make($request->all(), [ 'name' => 'required|string|max:255', 'email' => 'required|string|email|max:255|unique:users', 'password' => 'required|string|min:6|confirmed', ]); if ($validator->fails()) { return response(['errors'=>$validator->errors()->all()], 422); } $request['password']=Hash::make($request['password']); $user = User::create($request->toArray()); $token = $user->createToken('Laravel Password Grant Client')->accessToken; $response = ['token' => $token]; return response($response, 200); } public function login (Request $request) { $user = User::where('email', $request->email)->first(); if ($user) { if (Hash::check($request->password, $user->password)) { $token = $user->createToken('Laravel Password Grant Client')->accessToken; $response = ['token' => $token]; return response($response, 200); } else { $response = "Password missmatch"; return response($response, 422); } } else { $response = 'User does not exist'; return response($response, 422); } } public function logout (Request $request) { $token = $request->user()->token(); $token->revoke(); $response = 'You have been succesfully logged out!'; return response($response, 200); }
Setelah itu, Anda dapat menggunakan api/register, api/login, api/logout
metode api/register, api/login, api/logout
untuk otorisasi, dan memblokir akses ke api. Untuk melakukan ini, kita perlu membungkus perutean pengendali REST kami di middleware:
Route::middleware('auth:api')->group(function () { ... Route::get('/logout', 'Api\AuthController@logout')->name('logout'); });
Kata penutupKata penutup:
Masih akan ada untuk melakukan tes fungsional dan generasi dokumentasi dalam kesombongan, tapi ini sedikit di luar lingkup tutorial perancah, jadi lebih pada waktu lain