REST-API auf Laravel in 100 Codezeilen

inb4: Kopieren Einfügen aus der Dokumentation


Der Leitfaden konzentriert sich auf die schnelle Bereitstellung eines minimalen Satzes für eine vollwertige API-Entwicklung gemäß Best Practice aus der Laravel 5.7-Dokumentation, die an einem Ort gesammelt wurde. Ich habe für mich und meine Kollegen als Spickzettel geschrieben, ich hoffe, es wird jemand anderem nützlich sein.


Voreinstellung


Wir setzen einen Rahmen


composer create-project --prefer-dist laravel/laravel scaffold-api


Entfernen Sie unnötige UI-Komponenten (vuejs, reagieren)


php artisan preset none


Konfigurieren Sie die Datenbankverbindung


Gehen Sie zum Ordner und bearbeiten Sie die .env-Datei:


 DB_CONNECTION=mysql DB_HOST=localhost DB_PORT=3306 DB_DATABASE=api-authentification DB_USERNAME=root DB_PASSWORD= 

Erste Schritte beim Generieren


Wir führen in der Konsole aus
php artisan make:model Game -mrc


Wir bekommen das Modell, die Migration und den Controller:


 Model created successfully. Factory created successfully. Created Migration: 2019_02_27_105610_create_games_table Controller created successfully. 

Erstellen Sie Spalten in der Datenbanktabelle


Wir korrigieren die Migration, indem wir der Tabelle Spalten hinzufügen. Am häufigsten verwendete Typen:


  • increments('id')
  • string('title')
  • text('description')
  • tinyInteger('complexity')
  • boolean('isActive')
  • softDeletes()

Vergessen Sie bei optionalen Feldern nicht, den Standardwert mit ->default() hinzuzufügen.


Wenden Sie Migrationen an, indem Sie php artisan migrate


Wir generieren Validierungsregeln


Laufen php artisan make:request GameRequest


Öffne App/Http/Requests/GameRequest.php .
Setzen Sie in der authorize() -Methode return true bis wir die Autorisierung hinzufügen.
Das Array, das in der rules() -Methode zurückgegeben wird, beschreibt die Regeln für alle Spalten, die wir in der Migration aufgelistet haben. Verfügbare Regeln hier


Um den Code zu minimieren, verwenden wir das switch-Konstrukt für verschiedene http-Verben, anstatt separate StoreGameRequest, UpdateGameRequest usw. auszuführen.


 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' ]; } } 

Benutzerdefinierte Fehlerbeschreibungsoptionen


Wenn Sie Ihre eigenen Fehlertexte benötigen, definieren wir die Methode messages () neu, die ein Array mit Übersetzungen jeder Regel zurückgibt:


 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', ]; } 

Um sicherzustellen, dass nicht nur die im Anfragetext übergebenen Parameter, sondern auch die in der URL übergebenen Parameter in den Validierungsregeln verfügbar sind, definieren wir die Methode all neu (die normalerweise im Controller in Form von $ request-> all () verwendet wird):


 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; } 

Wir konfigurieren den Controller und beschreiben die Geschäftslogik


Öffnen Sie Http\Controllers\GameController . Wir entfernen die generierten Methoden create(), edit() die zum Rendern von Formularen bestimmt sind (da wir eine REST-API haben, werden sie nicht benötigt).


Ersetzen Sie die Standardverwendung use Illuminate\Http\Request; , bei unserer use App\Http\Requests\GameRequest;


Bearbeiten Sie als Nächstes die Methoden:


 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); } 

Wenn es viel Logik gibt, ist es besser, sie in einem separaten Layer Service / Repository zu platzieren


Passen Sie das Modell an


Öffnen Sie das Modell app / Http / Game.php und fügen Sie die folgenden Eigenschaften hinzu:


 protected $fillable = ['title', 'description', 'complexity', 'minPlayers', 'maxPlayers', 'isActive']; protected $hidden = ['created_at', 'updated_at', 'deleted_at']; 

Middleware konfigurieren


Damit unsere Anwendung unabhängig von den übergebenen Headern immer json zurückgibt, erstellen wir Middleware:


 php artisan make:middleware ForceJsonResponse 

und fügen Sie den Code hinzu:


 public function handle($request, Closure $next) { $request->headers->set('Accept', 'application/json'); return $next($request); } 

Registrieren Sie diese Middleware in app/Http/Kernel.php :


 ... 'api' => [ 'throttle:60,1', 'bindings', \App\Http\Middleware\ForceJsonResponse::class, ], 

Wir konfigurieren das Routing


Öffnen Sie routes/api.php und fügen routes/api.php hinzu:


 use Http\Controllers\GameController; Route::apiResource('/games', 'GameController'); 

Die statische Route :: apiResource-Methode schließt im Gegensatz zur Ressourcenmethode die Bearbeitungs- und Erstellungsmethoden aus und lässt nur indexieren, anzeigen, speichern, aktualisieren, zerstören.


Das gleiche kann mit einer offensichtlicheren Aufzeichnung erreicht werden:


 Route::resource('/games', 'GameController')->only([ 'index', 'show', 'store', 'update', 'destroy' ]); 

Jetzt können Sie die Pfade mit dem Befehl php artisan route:list und verwenden.


REST API ist fertig!


Nachwort

Nachwort


Wenn Sie eine Genehmigung benötigen, reicht der Standard-Laravel-Pass aus.


Konfigurieren Sie die Laravel Passport-Autorisierung


 composer require laravel/passport php artisan make:auth php artisan passport:install php artisan migrate 

Fügen Sie das Laravel\Passport\HasApiTokens zum App\User Modell hinzu und rufen Sie Passport::routesmethod in der boot app/AuthServiceProvider :


 public function boot() { $this->registerPolicies(); Passport::routes(); } 

config/auth.php den Treiber in passport:


 'api' => [ 'driver' => 'passport', 'provider' => 'users', ], 

Erstellen Sie einen Controller für die Autorisierung 'php artisan make: controller Api / AuthController.php`


Fügen Sie dort den Code hinzu


 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); } 

Danach können Sie die Methoden api/register, api/login, api/logout für die Autorisierung verwenden und den Zugriff auf die API blockieren. Dazu müssen wir das Routing unserer REST-Controller in Middleware einbinden:


 Route::middleware('auth:api')->group(function () { ... Route::get('/logout', 'Api\AuthController@logout')->name('logout'); }); 

Nachwort

Nachwort:


In Swagger müssten noch Funktionstests und Dokumentationserstellung durchgeführt werden, aber dies würde den Rahmen des Gerüst-Tutorials etwas sprengen, also dazu ein anderes Mal mehr


Source: https://habr.com/ru/post/de441946/


All Articles