Как создать REST API на Laravel

Как создать REST API на Laravel

Laravel — один из самых популярных PHP-фреймворков, который предоставляет мощные инструменты для быстрой разработки REST API. В этом подробном руководстве мы пройдём весь путь: от установки проекта до настройки CORS и аутентификации. Статья ориентирована на разработчиков, желающих создать полноценный API с нуля.

Нужен сайт с нестандартным функционалом? Закажите разработку сложного сайта у нас.

Что такое REST API

REST (Representational State Transfer) — это архитектурный стиль взаимодействия компонентов приложения. API, построенный по принципам REST, использует стандартные HTTP-методы:

  • GET — получение данных
  • POST — создание ресурса
  • PUT/PATCH — обновление ресурса
  • DELETE — удаление ресурса

Данные обычно передаются в формате JSON, что делает API удобным для интеграции с фронтенд-приложениями и мобильными клиентами.

Шаг 1. Установка Laravel

Для начала убедитесь, что у вас установлен Composer и PHP версии 8.1 или выше. Создайте новый проект:

composer create-project laravel/laravel webexo-api
cd webexo-api

Запустите встроенный сервер разработки:

php artisan serve

Приложение будет доступно по адресу http://127.0.0.1:8000 (порт может отличаться).

Шаг 2. Настройка базы данных

Откройте файл .env и укажите параметры подключения к базе данных:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=webexo_api
DB_USERNAME=root
DB_PASSWORD=your_password

Шаг 3. Создание модели, миграции и контроллера

Laravel позволяет создать всё сразу одной командой. Создадим ресурс «Product»:

php artisan make:model Product -mcr

Флаги означают:

-m — создать миграцию
-c — создать контроллер
-r — сделать контроллер ресурсным

Откройте созданную миграцию в database/migrations и опишите структуру таблицы:

public function up(): void
{
    Schema::create('products', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->text('description')->nullable();
        $table->decimal('price', 10, 2);
        $table->integer('quantity')->default(0);
        $table->timestamps();
    });
}

Запустите миграцию:

php artisan migrate

Шаг 4. Настройка модели

Откройте файл app/Models/Product.php и укажите поля, доступные для массового заполнения:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    protected $fillable = [
        'name',
        'description',
        'price',
        'quantity',
    ];
}

Шаг 5. Маршрутизация API

В Laravel маршруты API описываются в файле routes/api.php. Если файла нет (в новых версиях), установите API-роутинг командой:

php artisan install:api

Добавьте ресурсный маршрут:

<?php

use App\Http\Controllers\ProductController;
use Illuminate\Support\Facades\Route;

Route::apiResource('products', ProductController::class);

Одна строка создаёт сразу пять маршрутов:

МетодURIДействие
GET/api/productsindex
POST/api/productsstore
GET/api/products/{id}show
PUT/api/products/{id}update
DELETE/api/products/{id}destroy

Проверить список маршрутов можно командой:

php artisan route:list

Шаг 6. Создание API Resource

Чтобы контролировать формат ответа, используем ресурсы. Создадим их:

php artisan make:resource ProductResource

Откройте app/Http/Resources/ProductResource.php:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class ProductResource extends JsonResource
{
    public function toArray($request): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'description' => $this->description,
            'price' => (float) $this->price,
            'quantity' => $this->quantity,
            'created_at' => $this->created_at->toDateTimeString(),
        ];
    }
}

Шаг 7. Валидация запросов

Создадим Form Request для валидации входящих данных:

php artisan make:request StoreProductRequest

В файле app/Http/Requests/StoreProductRequest.php:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreProductRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        return [
            'name' => 'required|string|max:255',
            'description' => 'nullable|string',
            'price' => 'required|numeric|min:0',
            'quantity' => 'integer|min:0',
        ];
    }
}

Шаг 8. Реализация контроллера

Теперь напишем логику для контроллера app/Http/Controllers/ProductController.php:

<?php

namespace App\Http\Controllers;

use App\Http\Requests\StoreProductRequest;
use App\Http\Resources\ProductResource;
use App\Models\Product;
use Illuminate\Http\JsonResponse;

class ProductController extends Controller
{
    public function index(): JsonResponse
    {
        $products = Product::paginate(15);
        return ProductResource::collection($products)->response();
    }

    public function store(StoreProductRequest $request): JsonResponse
    {
        $product = Product::create($request->validated());
        return (new ProductResource($product))
            ->response()
            ->setStatusCode(201);
    }

    public function show(Product $product): JsonResponse
    {
        return (new ProductResource($product))->response();
    }

    public function update(StoreProductRequest $request, Product $product): JsonResponse
    {
        $product->update($request->validated());
        return (new ProductResource($product))->response();
    }

    public function destroy(Product $product): JsonResponse
    {
        $product->delete();
        return response()->json(null, 204);
    }
}

Laravel автоматически находит модель по ID из URL и подставляет её в метод. Если товар не найден, вернётся ошибка 404.

Шаг 9. Аутентификация через Sanctum

Для защиты API используем Laravel Sanctum. Он уже установлен через install:api. Добавим трейт в модель User:

use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;
}

Создадим маршрут для получения токена:

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use App\Models\User;

Route::post('/login', function (Request $request) {
    $request->validate([
        'email' => 'required|email',
        'password' => 'required',
    ]);

    $user = User::where('email', $request->email)->first();

    if (! $user || ! Hash::check($request->password, $user->password)) {
        return response()->json(['message' => 'Неверные данные'], 401);
    }

    $token = $user->createToken('api-token')->plainTextToken;

    return response()->json(['token' => $token]);
});

Защитим маршруты товаров middleware auth:sanctum:

Route::middleware('auth:sanctum')->group(function () {
    Route::apiResource('products', ProductController::class);
});

Теперь клиент должен передавать токен в заголовке:

Authorization: Bearer <ваш_токен>

Шаг 10. Настройка CORS

CORS (Cross-Origin Resource Sharing) необходим, когда фронтенд размещён на другом домене. В Laravel настройки CORS находятся в файле config/cors.php. Если файла нет, опубликуйте его:

php artisan config:publish cors

Пример конфигурации:

<?php

return [
    'paths' => ['api/*', 'sanctum/csrf-cookie'],
    'allowed_methods' => ['*'],
    'allowed_origins' => ['http://localhost:3000'],
    'allowed_origins_patterns' => [],
    'allowed_headers' => ['*'],
    'exposed_headers' => [],
    'max_age' => 0,
    'supports_credentials' => true,
];

Разберём ключевые параметры:

  • paths — пути, к которым применяются правила CORS
  • allowed_origins — разрешённые домены (используйте конкретные адреса вместо * в продакшене)
  • allowed_methods — разрешённые HTTP-методы
  • supports_credentials — разрешает передачу cookie и заголовков авторизации

После изменения конфигурации очистите кэш:

php artisan config:clear

Шаг 11. Обработка ошибок

Для единообразных ответов настройте обработку исключений в bootstrap/app.php:

->withExceptions(function (Exceptions $exceptions) {
    $exceptions->render(function (NotFoundHttpException $e, $request) {
        if ($request->is('api/*')) {
            return response()->json([
                'message' => 'Ресурс не найден'
            ], 404);
        }
    });
})

Шаг 12. Тестирование API

Проверить работу API можно через curl:

curl -X POST http://127.0.0.1:8000/api/products \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{"name":"Холодильник","price":50000,"quantity":10}'

Пример успешного ответа:

{
  "data": {
    "id": 1,
    "name": "Холодильник",
    "description": null,
    "price": 50000,
    "quantity": 10,
    "created_at": "2024-01-15 12:30:00"
  }
}

Для удобства используйте инструменты Postman или Insomnia.

Заключение

Мы прошли полный цикл создания REST API на Laravel: настроили маршрутизацию, создали модели и миграции, реализовали валидацию с помощью Form Requests, форматировали ответы через API Resources, добавили аутентификацию через Sanctum и настроили CORS для работы с внешними клиентами.

Laravel значительно упрощает разработку API благодаря продуманной архитектуре и богатому набору встроенных инструментов. Для дальнейшего развития рекомендую изучить версионирование API и ограничение частоты запросов (rate limiting). Соблюдение принципов REST и грамотная организация кода помогут создать надёжный и масштабируемый интерфейс для ваших приложений.