Урок 04

Resource-контроллеры для API

Создание

php artisan make:controller Api/PostController --api --model=Post

--api создаёт контроллер без create и edit — в API нет HTML-форм.

Структура

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Resources\PostResource;
use App\Models\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{
    public function index() {}
    public function store(Request $request) {}
    public function show(Post $post) {}
    public function update(Request $request, Post $post) {}
    public function destroy(Post $post) {}
}

Регистрация

use App\Http\Controllers\Api\PostController;

Route::apiResource('posts', PostController::class);

Создаёт 5 маршрутов:

МетодURLДействие
GET/api/postsindex
POST/api/postsstore
GET/api/posts/{post}show
PUT/PATCH/api/posts/{post}update
DELETE/api/posts/{post}destroy

Реализация index

public function index()
{
    $posts = Post::with('user')
        ->withCount('comments')
        ->latest()
        ->paginate(15);

    return PostResource::collection($posts);
}

Реализация store

public function store(Request $request)
{
    $data = $request->validate([
        'title' => 'required|string|max:255',
        'body' => 'required|string|min:10',
    ]);

    $post = $request->user()->posts()->create($data);

    return (new PostResource($post))->response()->setStatusCode(201);
}

Реализация update

public function update(Request $request, Post $post)
{
    $data = $request->validate([
        'title' => 'sometimes|required|string|max:255',
        'body' => 'sometimes|required|string|min:10',
    ]);

    $post->update($data);

    return new PostResource($post);
}

Реализация destroy

public function destroy(Post $post)
{
    $post->delete();

    return response()->noContent();
}

Частичные ресурсы

Только нужные действия:

Route::apiResource('posts', PostController::class)->only(['index', 'show']);
Route::apiResource('posts', PostController::class)->except(['destroy']);

Вложенные ресурсы

Route::apiResource('posts.comments', CommentController::class);

URL: /api/posts/{post}/comments/{comment}.