6 лучших практик Laravel RESTful APIs
Создание хороших API является одним из основных навыков успешного backend-разработчика. Они являются основой ваших любимых мобильных приложений или одностраничных приложений.
Laravel предоставляет множество инструментов, которые помогут создать API стандартным способом. В этой статье я буду исходить из того, что вы уже создали хотя бы один API, поскольку цель статьи — не охватить всю тему целиком.
Использование правильного HTTP метода
HTTP методы — это своего рода язык, на котором говорит ваш веб-сервер. Когда создаёте API, вы тоже должны говорить на этом языке.
Использование правильных HTTP методов очень важно, поскольку позволяет повысить эффективность взаимодействия с API и сделать его более интуитивно понятным для использующих его разработчиков.
Например, допустим, у нас есть электронная книга в библиотеке. Если мы хотим прочитать её, то используем метод GET
. Если мы хотим добавить в библиотеку новую книгу, то используем метод POST
. Для обновления информации в существующей книге используется метод PUT
или PATCH
(честно говоря, я до сих пор не понимаю разницы и по умолчанию использую PUT
). И, наконец, когда хотим удалить книгу из библиотеки, используем метод DELETE
.
Как Laravel может помочь в этом? Он предоставляет простые в использовании маршруты, которые соответствуют этим HTTP методам:
Route::get('/posts', [PostController::class, 'index']);
Route::get('/posts/{post}', [PostController::class, 'show']);
Route::post('/posts', [PostController::class, 'store']);
Route::put('/posts/{post}', [PostController::class, 'update']);
Route::delete('/posts/{post}', [PostController::class, 'destroy']);
Если вы мало что знаете о HTTP, я бы посоветовал провести быстрый поиск в Google, чтобы ознакомиться с ними. Я все ещё не писал о них (пока).
Использование маршрутов API ресурсов
Laravel предоставляет простой и удобный способ создания маршрутов API с помощью метода apiResource
. Это помогает разработчикам быстро создавать маршруты для API.
Вот как это работает:
В Laravel apiResource
— метод, автоматически включающий основные маршруты, необходимые для API. Он создаёт маршруты для методов index, store, show, update и destroy, исключая create и edit, поскольку эти два метода обычно используются для возврата HTML-представлений, которые нам не нужны в API.
Например:
use App\Http\Controllers\PhotoController;
Route::apiResource('photos', PhotoController::class);
В приведённом выше коде photos
— это URL, а PhotoController
— класс, который обрабатывает запросы к этому URL.
Если вы хотите создать маршруты сразу для нескольких контроллеров, просто используйте метод apiResources
и передайте массив, содержащий пары 'url' => 'Controller'
, следующим образом:
use App\Http\Controllers\PhotoController;
use App\Http\Controllers\PostController;
Route::apiResources([
'photos' => PhotoController::class,
'posts' => PostController::class,
]);
Это автоматически задаёт URL photos
и posts
, которые будут обрабатываться PhotoController
и PostController
соответственно.
Наконец, при создании нового контроллера для API в Laravel предусмотрена удобная команда php artisan make:controller ControllerName --api
. Добавление опции --api
сообщит Laravel, что этот контроллер предназначен для API, и исключит методы create и edit в коде шаблона.
Laravel действительно позволяет легко настроить API!
Использование API ресурсов Eloquent
Ресурсы API — это способ превращения моделей данных в пригодные для использования структуры JSON. Они обеспечивают уровень преобразования между моделями и ответами API вашего приложения.
Рассматривайте их как посредников. Они получают данные из ваших моделей, перемешивают их или фильтруют, а затем передают в виде ответа в формате JSON.
При создании класса ресурса можно определить способ сопоставления атрибутов из модели с JSON-представлением. Вы просто используете метод toArray
, чтобы вернуть массив, соответствующий структуре, которую вы хотите получить в JSON-ответе. При этом доступ к свойствам модели можно получить прямо из объекта ресурса.
Приведём пример:
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
];
}
Создание ресурсов осуществляется с помощью команды Artisan make:resource
. Например, если вы хотите создать ресурс UserResource
, вы должны выполнить команду:
php artisan make:resource UserResource
Вы также можете создавать коллекции ресурсов, используя make:resource
с флагом --collection
или добавляя Collection
к имени ресурса.
Приведём пример "коллекции" UserResource
:
php artisan make:resource User --collection
Или,
php artisan make:resource UserCollection
В Laravel эти ресурсы используются при формировании ответов от маршрута или контроллера.
Для отдельного ресурса достаточно вернуть новый экземпляр ресурса, созданный с моделью, которую необходимо преобразовать:
Route::get('/user/{id}', function (string $id) {
return new UserResource(User::findOrFail($id));
});
Для коллекций используется метод collection
ресурсного класса:
Route::get('/users', function () {
return UserResource::collection(User::all());
});
Я рекомендую ознакомиться с полной документацией Laravel по ресурсам API, если вы хотите узнать о расширенных возможностях и других сценариях использования.
Использование JSON ответов
При возврате ресурса Eloquent в контроллере Laravel автоматически формирует JSON ответ.
В противном случае на помощь приходит метод json
, автоматически устанавливающий для заголовка Content-Type
значение application/json
и преобразующий заданный массив в JSON:
return response()->json([
'foo' => 'bar',
]);
Использование правильного HTTP-кода для ответов
Возврат правильного HTTP-кода в ответе имеет решающее значение.
В своей карьере вы наверняка сталкивались с ужасными API, возвращающими код состояния 200
с {"message": "Error!" }
или что-то в этом роде. Пожалуйста, не будьте таким разработчиком!
Мы хотим, чтобы наши API были как можно более информативными. Вот хорошая отправная точка, которая подойдёт практически для всех случаев использования:
- Список и получение ресурсов: 200 (OK).
- Создание ресурсов: 201 (Created).
- Обновление ресурсов: 200 (OK).
- Удаление ресурсов: 204 (No Content).
- Для доступа к ресурсам требуется аутентификация: 401 (Forbidden).
- Неавторизованный доступ к ресурсам: 403 (Unauthorized).
- Ресурсы отсутствуют: 404 (Not Found).
- Что-то пошло не так: 500 (Internal Server Error).
Laravel предоставляет удобный помощник response()
, позволяющий указать HTTP-код, который необходимо включить в ответ:
return response(
['foo' => 'bar'],
201
);
Вернуть пустой ответ с кодом состояния 204
:
response()->noContent();
Ресурс требует аутентификации, не авторизован, отсутствует или что-то пошло не так:
abort(401);
abort(403);
abort(404);
abort(500);
Кстати, если у вас есть подходящий вариант использования кода состояния 418
(я чайник), дайте мне знать!
Экономия времени на аутентификацию с помощью Laravel Sanctum или Passport
Нюансы между этими двумя пакетами всегда сложно объяснять. Но давайте попробуем:
Laravel Passport можно использовать в тех случаях, когда для аутентификации пользователей требуется аутентификация, аналогичная Facebook, Google, X (бывший Twitter) и т.д.
Laravel Sanctum, с другой стороны, представляет собой менее строгую систему аутентификации, которая лучше всего подходит для простых проектов, таких как одностраничные или мобильные приложения.
В общем, если вы все ещё не уверены в своих силах, вместо того, чтобы застрять, используйте сначала Laravel Sanctum и переходите на Passport, если вашему приложению потребуется что-то более продвинутое. Вы поймёте это, когда придёт время!