inb4: рдбреЙрдХреНрдпреВрдореЗрдВрдЯ рд╕реЗ рдХреЙрдкреА рдкреЗрд╕реНрдЯ
рдЧрд╛рдЗрдб рдПрдХ рдЬрдЧрд╣ рдкрд░ рдПрдХрддреНрд░ рдХрд┐рдП рдЧрдП рд▓рд╛рд░рд╡реЗрд▓ 5.7 рдкреНрд░рд▓реЗрдЦрди рд╕реЗ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдЕрднреНрдпрд╛рд╕ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдкреВрд░реНрдг рд╡рд┐рдХрд╕рд┐рдд рдПрдкреАрдЖрдИ рд╡рд┐рдХрд╛рд╕ рдХреЗ рд▓рд┐рдП рдиреНрдпреВрдирддрдо рд╕реЗрдЯ рдХреА рддреЗрдЬреА рд╕реЗ рддреИрдирд╛рддреА рдкрд░ рдХреЗрдВрджреНрд░рд┐рдд рд╣реИред рдореИрдВрдиреЗ рдЕрдкрдиреЗ рдФрд░ рдЕрдкрдиреЗ рд╕рд╣рдпреЛрдЧрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдзреЛрдЦрд╛ рдкрддреНрд░ рдХреЗ рд░реВрдк рдореЗрдВ рд▓рд┐рдЦрд╛, рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рдХрд┐рд╕реА рдФрд░ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ред
рдкреНрд░реАрд╕реЗрдЯ
рд╣рдордиреЗ рдПрдХ рдврд╛рдВрдЪрд╛ рд░рдЦрд╛
composer create-project --prefer-dist laravel/laravel scaffold-api
рдЕрдирд╛рд╡рд╢реНрдпрдХ UI рдШрдЯрдХ рдирд┐рдХрд╛рд▓реЗрдВ (vuejs, рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛)
php artisan preset none
рдбреЗрдЯрд╛рдмреЗрд╕ рдХрдиреЗрдХреНрд╢рди рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВ
рдлрд╝реЛрд▓реНрдбрд░ рдкрд░ рдЬрд╛рдПрдВ, .env рдлрд╝рд╛рдЗрд▓ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ:
DB_CONNECTION=mysql DB_HOST=localhost DB_PORT=3306 DB_DATABASE=api-authentification DB_USERNAME=root DB_PASSWORD=
рдЙрддреНрдкрд╛рджрди рд╢реБрд░реВ рд╣реЛ рд░рд╣рд╛ рд╣реИ
рд╣рдо рдХрдВрд╕реЛрд▓ рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╣реИрдВ
php artisan make:model Game -mrc
рд╣рдореЗрдВ рдореЙрдбрд▓, рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдФрд░ рдХрдВрдЯреНрд░реЛрд▓рд░ рдорд┐рд▓рддрд╛ рд╣реИ:
Model created successfully. Factory created successfully. Created Migration: 2019_02_27_105610_create_games_table Controller created successfully.
рдбреЗрдЯрд╛рдмреЗрд╕ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдХреЙрд▓рдо рдмрдирд╛рдПрдВ
рд╣рдо рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдХреЙрд▓рдо рдЬреЛрдбрд╝рдХрд░ рдкреНрд░рд╡рд╛рд╕ рдХреЛ рд╕рд╣реА рдХрд░рддреЗ рд╣реИрдВред рдЖрдорддреМрд░ рдкрд░ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдкреНрд░рдХрд╛рд░:
increments('id')
string('title')
text('description')
tinyInteger('complexity')
boolean('isActive')
softDeletes()
рд╡реИрдХрд▓реНрдкрд┐рдХ рдлрд╝реАрд▓реНрдб рдХреЗ рд▓рд┐рдП, ->default()
рд╕рд╛рде рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рдЬреЛрдбрд╝рдирд╛ рди рднреВрд▓реЗрдВ
php artisan migrate
рдХрд░рдХреЗ рдкрд▓рд╛рдпрди рд▓рд╛рдЧреВ рдХрд░реЗрдВ
рд╣рдо рд╕рддреНрдпрд╛рдкрди рдирд┐рдпрдо рдмрдирд╛рддреЗ рд╣реИрдВ
рд░рдирд┐рдВрдЧ php artisan make:request GameRequest
App/Http/Requests/GameRequest.php
ред
authorize()
рд╡рд┐рдзрд┐ рдореЗрдВ, рд╣рдо рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдЬреЛрдбрд╝рдиреЗ рддрдХ return true
ред
rules()
рд╡рд┐рдзрд┐ рдореЗрдВ рджреА рдЧрдИ рд╕рд╛рд░рдгреА рдЙрди рд╕рднреА рд╕реНрддрдВрднреЛрдВ рдХреЗ рдирд┐рдпрдореЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреА рд╣реИ рдЬрд┐рдиреНрд╣реЗрдВ рд╣рдордиреЗ рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдореЗрдВ рд╕реВрдЪреАрдмрджреНрдз рдХрд┐рдпрд╛ рдерд╛ред рдпрд╣рд╛рдВ рдЙрдкрд▓рдмреНрдз рдирд┐рдпрдо
рдХреЛрдб рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЕрд▓рдЧ-рдЕрд▓рдЧ http рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рд┐рдЪ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдмрдЬрд╛рдп рдЕрд▓рдЧ StoreGameRequest, UpdateGameRequest, рдЖрджрд┐ рдХреЗред
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' ]; } }
рдХрд╕реНрдЯрдо рддреНрд░реБрдЯрд┐ рд╡рд┐рд╡рд░рдг рд╡рд┐рдХрд▓реНрдк
рдпрджрд┐ рдЖрдкрдХреЛ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рддреНрд░реБрдЯрд┐ рдЧреНрд░рдВрдереЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рд╣рдо рд╕рдВрджреЗрд╢реЛрдВ () рд╡рд┐рдзрд┐ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рдкреНрд░рддреНрдпреЗрдХ рдирд┐рдпрдо рдХреЗ рдЕрдиреБрд╡рд╛рдж рдХреЗ рд╕рд╛рде рдПрдХ рд╕рд░рдгреА рджреЗрддрд╛ рд╣реИ:
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', ]; }
рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рди рдХреЗрд╡рд▓ рдЕрдиреБрд░реЛрдз рдирд┐рдХрд╛рдп рдореЗрдВ рдкрд╛рд░рд┐рдд рдкреИрд░рд╛рдореАрдЯрд░, рдмрд▓реНрдХрд┐ URL рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд┐рдП рдЧрдП рдкреИрд░рд╛рдореАрдЯрд░ рднреА рд╕рддреНрдпрд╛рдкрди рдирд┐рдпрдореЛрдВ рдореЗрдВ рдЙрдкрд▓рдмреНрдз рд╣реИрдВ, рд╣рдо рд╕рднреА рд╡рд┐рдзрд┐ рдХреЛ рдкреБрдирд░реНрдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ (рдЬреЛ рдЖрдорддреМрд░ рдкрд░ $ рдЕрдиреБрд░реЛрдз рдХреЗ рд░реВрдк рдореЗрдВ рдирд┐рдпрдВрддреНрд░рдХ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ-> рд╕рднреА) ():
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; }
рд╣рдо рдирд┐рдпрдВрддреНрд░рдХ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рд╡реНрдпрд╛рдкрд╛рд░рд┐рдХ рддрд░реНрдХ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВ
Http\Controllers\GameController
ред рд╣рдо рд░реЗрдВрдбрд░ рдлреЙрд░реНрдо рдХреЗ рд▓рд┐рдП рдЬреЗрдирд░реЗрдЯ create(), edit()
рддрд░реАрдХреЗ рд╣рдЯрд╛рддреЗ рд╣реИрдВ (рдХреНрдпреЛрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ REST API рд╣реИ, рдЙрдирдХреА рдЬрд░реВрд░рдд рдирд╣реАрдВ рд╣реИ)ред
рдорд╛рдирдХ use Illuminate\Http\Request;
рдмрджрд▓реЗрдВ use Illuminate\Http\Request;
рд╣рдорд╛рд░реЗ use App\Http\Requests\GameRequest;
рдкрд░, use App\Http\Requests\GameRequest;
рдЕрдЧрд▓рд╛, рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ:
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); }
рдпрджрд┐ рдмрд╣реБрдд рддрд░реНрдХ рд╣реИ, рддреЛ рдЗрд╕реЗ рдПрдХ рдЕрд▓рдЧ рдкрд░рдд рд╕реЗрд╡рд╛ / рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рд░рдЦрдирд╛ рдмреЗрд╣рддрд░ рд╣реИ
рдореЙрдбрд▓ рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░реЗрдВ
рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЦреЛрд▓реЗрдВ / Http / Game.php рдореЙрдбрд▓ рдФрд░ рдЧреБрдг рдЬреЛрдбрд╝реЗрдВ:
protected $fillable = ['title', 'description', 'complexity', 'minPlayers', 'maxPlayers', 'isActive']; protected $hidden = ['created_at', 'updated_at', 'deleted_at'];
рдорд┐рдбрд▓рд╡реЗрдпрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВ
рддрд╛рдХрд┐ рд╣рдорд╛рд░реЗ рдЖрд╡реЗрджрди рд╣рдореЗрд╢рд╛ рд╣реЗрдбрд░ рдкрд╛рд░рд┐рдд рдХреА рдкрд░рд╡рд╛рд╣ рдХрд┐рдП рдмрд┐рдирд╛ рд╡рд╛рдкрд╕ рд▓реМрдЯ рдЖрдП, рд╣рдо рдорд┐рдбрд▓рд╡реЗрдпрд░ рдмрдирд╛рддреЗ рд╣реИрдВ:
php artisan make:middleware ForceJsonResponse
рдФрд░ рдЗрд╕рдореЗрдВ рдХреЛрдб рдЬреЛрдбрд╝реЗрдВ:
public function handle($request, Closure $next) { $request->headers->set('Accept', 'application/json'); return $next($request); }
рдЗрд╕ рдорд┐рдбрд▓рд╡реЗрдпрд░ рдХреЛ app/Http/Kernel.php
рдореЗрдВ рдкрдВрдЬреАрдХреГрдд рдХрд░реЗрдВ:
... 'api' => [ 'throttle:60,1', 'bindings', \App\Http\Middleware\ForceJsonResponse::class, ],
рд╣рдо рд░реВрдЯрд┐рдВрдЧ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рддреЗ рд╣реИрдВ
рдЦреБрд▓реЗ routes/api.php
рдФрд░ рдЬреЛрдбрд╝реЗрдВ:
use Http\Controllers\GameController; Route::apiResource('/games', 'GameController');
рд╕реНрдерд┐рд░ рдорд╛рд░реНрдЧ :: apiResource рд╡рд┐рдзрд┐, рд╕рдВрд╕рд╛рдзрди рд╡рд┐рдзрд┐ рдХреЗ рд╡рд┐рдкрд░реАрдд, рдХреЗрд╡рд▓ рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛, рд╢реЛ, рд╕реНрдЯреЛрд░, рдЕрдкрдбреЗрдЯ рдХреЛ рдирд╖реНрдЯ рдХрд░рдиреЗ, рдирд╖реНрдЯ рдХрд░рдиреЗ рдФрд░ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЛрдВ рдХреЛ рдЫреЛрдбрд╝рдХрд░ред
рд╡рд╣реА рдЕрдзрд┐рдХ рд╕реНрдкрд╖реНрдЯ рд░рд┐рдХреЙрд░реНрдб рдХреЗ рд╕рд╛рде рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
Route::resource('/games', 'GameController')->only([ 'index', 'show', 'store', 'update', 'destroy' ]);
рдЕрдм, рдЖрдк php artisan route:list
рд╕рд╛рде рдкрде рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ php artisan route:list
рдХрдорд╛рдВрдб рдФрд░ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред
рдмрд╛рдХреА рдПрдкреАрдЖрдИ рддреИрдпрд╛рд░ рд╣реИ!
рдЕрдВрддрднрд╛рд╖рдгрдЕрдВрддрднрд╛рд╖рдг
рдпрджрд┐ рдЖрдкрдХреЛ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдорд╛рдирдХ рд▓рд╛рд░рд╡реЗрд▓ рдкрд╛рд╕рдкреЛрд░реНрдЯ рдХрд░реЗрдЧрд╛ред
рд▓рд╛рд░рд╡реЗрд▓ рдкрд╛рд╕рдкреЛрд░реНрдЯ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВ
composer require laravel/passport php artisan make:auth php artisan passport:install php artisan migrate
App\User
рдореЙрдбрд▓ рдореЗрдВ Laravel\Passport\HasApiTokens
рдЬреЛрдбрд╝реЗрдВ рдФрд░ Passport::routesmethod
рдХреЙрд▓ рдХрд░реЗрдВ Passport::routesmethod
boot
app/AuthServiceProvider
:
public function boot() { $this->registerPolicies(); Passport::routes(); }
config/auth.php
рдбреНрд░рд╛рдЗрд╡рд░ рдХреЛ рдкрд╛рд╕рдкреЛрд░реНрдЯ рдореЗрдВ рдмрджрд▓реЗрдВ:
'api' => [ 'driver' => 'passport', 'provider' => 'users', ],
рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдирд┐рдпрдВрддреНрд░рдХ рдмрдирд╛рдПрдВ 'php рдХрд╛рд░реАрдЧрд░ рдмрдирд╛рддреЗ рд╣реИрдВ: рдирд┐рдпрдВрддреНрд░рдХ Api / AuthController.php`
рд╡рд╣рд╛рдВ рдХреЛрдб рдЬреЛрдбрд╝реЗрдВ
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); }
рдЙрд╕рдХреЗ рдмрд╛рдж, рдЖрдк рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХреЗ рд▓рд┐рдП api/register, api/login, api/logout
рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ api/register, api/login, api/logout
рддрдХ рдкрд╣реБрдВрдЪ рдХреЛ рдЕрд╡рд░реБрджреНрдз рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЕрдкрдиреЗ REST рдирд┐рдпрдВрддреНрд░рдХреЛрдВ рдХреЛ рдорд┐рдбрд▓рд╡реЗрдпрд░ рдореЗрдВ рд░реВрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛:
Route::middleware('auth:api')->group(function () { ... Route::get('/logout', 'Api\AuthController@logout')->name('logout'); });
PosleposlesloviePosleposleslovie:
рдЕрднреА рднреА рд╕реНрд╡реИрдЧрд░ рдореЗрдВ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкрд░реАрдХреНрд╖рдг рдФрд░ рдкреНрд░рд▓реЗрдЦрди рдкреАрдврд╝реА рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдпрд╣ рд╕реНрдХреИрдлреЛрд▓реНрдб рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреЗ рджрд╛рдпрд░реЗ рд╕реЗ рдереЛрдбрд╝рд╛ рдкрд░реЗ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЙрд╕ рдкрд░ рдПрдХ рдФрд░ рд╕рдордп