рдХреЛрдб рдХреА 100 рд▓рд╛рдЗрдиреЛрдВ рдореЗрдВ Laravel рдкрд░ REST API

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

Posleposleslovie

Posleposleslovie:


рдЕрднреА рднреА рд╕реНрд╡реИрдЧрд░ рдореЗрдВ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкрд░реАрдХреНрд╖рдг рдФрд░ рдкреНрд░рд▓реЗрдЦрди рдкреАрдврд╝реА рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдпрд╣ рд╕реНрдХреИрдлреЛрд▓реНрдб рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреЗ рджрд╛рдпрд░реЗ рд╕реЗ рдереЛрдбрд╝рд╛ рдкрд░реЗ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЙрд╕ рдкрд░ рдПрдХ рдФрд░ рд╕рдордп


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


All Articles