Ответ
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
}
}