Подписывайся на Telegram-канал

Как правильно создавать API.

Как правильно создавать API.

https://t.me/it_programmist

Бывают задачи вроде таких:

- разработка проекта с использованием мощного форнтэнда (react, angular, vue)

- разработка мобильного приложения

- нужно дать доступ к некоторым функциям или данным для внешних сайтов/приложений

Для этих и многих других задач используется RESTful API.

Но даже на собственных проектах можно увидеть, что API разных проектов отличаются друг от друга.

Попробую обобщить некоторые моменты по созданию RESTful API.

Я не утверждаю, что это неоспоримые правила построения API и всё-таки многое зависит от задачи и ситуации, но какую-то общую структуру для себя выделить можно.

Это поможет с лёгкостью разбираться в своих старых проектах, а также поможет, если будет такая необходимость, другим разработчикам не впадать в ступор при виде кода, а быстро находить нужное.


У меня есть два основных правила для RESTfull API:

1. Поменьше креатива. То есть делать то, что ожидается.

2. Быть последовательным. То есть структуры запросов, ответов, заголовков должны быть одинаковы для всего API.


Правила семантики.


1. Существительные, а не глаголы

Лучше использовать


get /posts
get /posts/111
post /posts


чем


get /getAllPosts
get /getPostById/111
post /createPost


Первый пример более общий, понятный и привычный. Большинство разработчиков пользуются и привыкли именно к такому формату.


2. Будь аккуратнее с изменениями. Избегай изменений в конечных точках(семантика запроса и структура ответа)


Особенно, если API для внешнего доступа. Всегда хорошо исправить баги, но эти исправления не должны менять работу API. Если всё же вносятся кардинальные изменения, то нужно подумать об обратной совместимости или хотя бы о том, чтобы заранее предупредить всех, кто пользуется этим API.


3. Будь последовательным (Структура, ответы, общепринятые методы).


Лучшие практики:

- GET для получения данных

- PUT/POST для внесения изменений

- одинаковая структура конечных точек(формат запросов и формат ответов)

- хорошие и правильные коды состояния (если запрос сформирован неправильно, то следует использовать 400 код ответа сервера, а 404 и уже тем более не 200)


Не рекомендуется:

- использовать коды не те коды ответа. Если запрашивается список постов и он пуст, то лучше вернуть пустой список с кодом 200, а не отдать 404.

- использовать GET для внесения изменений, а PUT/POST для получения данных.

- не использовать сообщения об ошибках.


4. Используй версии.

Несмотря на описанное в пункте 2, изменения всё равно неизбежны. Изменится бизнес, изменятся процессы, изменится то, чего хотят люди. И API придётся менять.

Перед изменениями предусмотри версионность. Самый семантически верный и понятный способ это добавить версию в url.


/api/v2/posts


5. Не усложняй!


- не возвращай больше чем нужно. Если определённое свойство возвращаемых объектов является внутренним, то лучше его не возвращать.

- не нужно использовать все возможные коды ответа сервера. Достаточно привычных и часто используемых: 200, 201, 302, 404, 400, 500 и т. д.

- не повторяйся. Не делай несколько похожих методов.

- структура ответа должна быть одинаковой для всех методов.


6. Документация.

Ты будешь благодарен себе из прошлого и другие разработчики будут благодарны тебе, если к API будет документация. Для внутреннего пользования достаточно комментариев и самодокументируемого кода(об этом в следующих статьях).

Для внешних пользователей нобходимо сделать документацию. Можно воспользоваться атрибутами и автогенерацией API, это лучше чем ничего.


Технические правила (или, скорее, рекомендации)


1. Используй прослойку между запросом и базой данных



public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string Passport { get; set; } //ай ай ай
}

public class PersonsController : ApiController
{
public IHttpActionResult Put(int id, [FromBody] Person person)
{
//update the Person object
}
}



Видишь проблему? У пользователя есть возможность изменить или получить свойство Passport. То есть он может просто передать новое значение в метод и изменить его.

Да, безусловно можно передавать данные в обновлении поимённо, но не лучше ли сделать прослойку? Дай пользователю только то, что ему нужно. Это называется DTO(Data Transfer Object):

public class PersonDto
{
public int Id { get; set; }
public string Name { get; set; }
}

public class PersonsController : ApiController
{
public IHttpActionResult Put(int id, [FromBody] PersonDto person)
{
//update the Person object
}
}

2. Проверяй всё

Все данный должны считаться плохими пока не произведена какая-то проверка. Иначе рано или поздно какой-то запрос сломает твой API.

Например при оформлении заказа в интернет-магазине следует проверить наличие в заказе по крайней мере одного товара.

3. «Тонкие» контроллеры

Контролеры должны только принимать данные отдавать их службам и возвращать данные обратно. Бизнес-логики в контроллерах быть не должно.

4. Один метод — одно действие.

Раздели на простейшие составляющие весь API.

Один пользовательский метод — одно действие.

Один метод в модели — одно действие.

Упрощай и разделяй!

5 . Если есть возможность, то используй ассинхронность

Ты сам скажешь себе спасибо когда трафик на приложение вырастет!


Если есть вопросы, замечания или просто мнение пиши в клубе программистов t.me/progersclub

Больше полезного для программиста на канале «Я - программист!»

Ещё