Ответ
API считается RESTful, если он следует архитектурным ограничениям и принципам REST (Representational State Transfer):
- Единообразие интерфейса (Uniform Interface):
- Ресурсы: Данные представлены как ресурсы с уникальными идентификаторами (URI), например,
/api/users/123. - Манипуляции через представления: Клиент манипулирует ресурсом через представление (например, JSON), которое содержит достаточно информации для этого.
- Самодостаточные сообщения: Каждый запрос содержит всю информацию, необходимую для его обработки.
- HATEOAS (Hypermedia as the Engine of Application State): В идеале, ответы API содержат гиперссылки на возможные следующие действия, что делает API более открытым для обнаружения.
- Ресурсы: Данные представлены как ресурсы с уникальными идентификаторами (URI), например,
- Отсутствие состояния (Stateless): Сервер не хранит состояние клиента между запросами. Весь необходимый контекст (например, токен аутентификации) должен передаваться в каждом запросе.
- Кэшируемость (Cacheable): Ответы сервера должны явно указывать, можно ли их кэшировать и как долго, чтобы повысить производительность.
- Клиент-серверная архитектура: Четкое разделение обязанностей позволяет им развиваться независимо.
- Слоистая система (Layered System): Архитектура может включать промежуточные серверы (балансировщики, прокси, шлюзы), не влияя на взаимодействие клиента и сервера.
- Использование стандартных HTTP-методов:
GET— получение ресурса.POST— создание ресурса.PUT/PATCH— полное или частичное обновление ресурса.DELETE— удаление ресурса.
Пример RESTful эндпоинта на ASP.NET Core:
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
[HttpGet("{id}")] // GET /api/users/5
public ActionResult<UserDto> GetUser(int id)
{
var user = _repository.GetUser(id);
if (user == null) return NotFound(); // Корректный HTTP-статус 404
return Ok(user); // Статус 200 с данными
}
[HttpPost] // POST /api/users
public ActionResult<UserDto> CreateUser([FromBody] CreateUserDto userDto)
{
var newUser = _repository.AddUser(userDto);
return CreatedAtAction(nameof(GetUser),
new { id = newUser.Id },
newUser); // Статус 201 с заголовком Location
}
} Ответ 18+ 🔞
Давай я тебе на пальцах объясню, что такое этот ваш RESTful API, а то читаешь эти умные формулировки — голова квадратная становится, блядь.
Смотри, представь себе библиотеку, только цифровую. Вот есть у тебя полки с книгами — это ресурсы. Каждая книга на своей полке и у неё свой уникальный номер-адрес, типа /книги/война-и-мир. Это и есть первый принцип — единообразие интерфейса. Нельзя прийти и сказать: «Эй, дай-ка мне ту штуку, которая про Наполеона и про любовь!». Ты чётко называешь адрес. Идеальный REST ещё и ссылки тебе в ответ суёт: «Вот тебе книга, а если хочешь следующую главу — вот ссылка на неё, мудила». Это HATEOAS называется, но до него обычно всем похуй, если честно.
Дальше — отсутствие состояния. Это как общаться с золотой рыбкой, у которой память — три секунды. Ты ей в каждом запросе должен напоминать, кто ты такой: «Я — Вася, вот мой пропуск, дай мне книгу!». Сервер тебя между запросами не помнит вообще, ему похуй. Весь твой контекст — в каждом запросе.
Кэшируемость — это вообще святое. Сервер должен тебе чётко сказать: «Чувак, эта информация актуальна пять минут, можешь не дергаться». Или наоборот: «Этот ответ — говно свежее, не кэшируй его, нахуй». Иначе получишь старые данные и потом будешь ебаться, почему всё сломалось.
Клиент-сервер и слоистая система — это просто чтобы ты, как клиент, не лез в серверные дела, а сервер тебя не грузил своей хуйнёй. А между вами могут быть ещё прокси, балансировщики — куча слоёв, как в торте «Наполеон», но тебе от этого ни жарко ни холодно.
Ну и главное — использование HTTP-методов как бог завещал. Это не просто так, это священная война, блядь!
GET— посмотреть, почитать. Без изменений, просто смотри.POST— создать что-то новое, типа «запиши меня в библиотеку».PUT/PATCH— обновить запись.PUT— это «перепиши всю страницу заново», аPATCH— «исправь тут одну опечатку».DELETE— ну, удалить, ясен хуй. Отнести книгу в макулатуру.
А теперь смотри, как это выглядит в коде, если не быть идиотом:
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
[HttpGet("{id}")] // Запрос: Дай мне пользователя с ID=5 (GET /api/users/5)
public ActionResult<UserDto> GetUser(int id)
{
var user = _repository.GetUser(id);
// Если не нашли — возвращаем честный 404. Не надо выдумывать свою хуйню.
if (user == null) return NotFound();
// Нашли — окей, 200, держи данные.
return Ok(user);
}
[HttpPost] // Запрос: Вот тебе данные, создай нового пользователя (POST /api/users)
public ActionResult<UserDto> CreateUser([FromBody] CreateUserDto userDto)
{
var newUser = _repository.AddUser(userDto);
// Идеальный REST-ответ: статус 201 (Created) и в заголовках адрес, где этого нового юзера найти.
return CreatedAtAction(nameof(GetUser),
new { id = newUser.Id },
newUser);
}
}
Вот и вся магия. Если твой API так работает — он RESTful. Если ты GET-ом данные удаляешь, а POST-ом просто смотришь — ты пидор, извини. У тебя не REST, а дичь непонятная и все, кто с ним работают, тебя тихо ненавидят.