Ответ
Качественный Web API (чаще всего RESTful) строится на общепринятых принципах, которые обеспечивают его стабильность, предсказуемость и удобство использования.
-
Единообразие интерфейса (Uniform Interface). Использование стандартных HTTP-методов для операций с ресурсами:
GET— получение данных.POST— создание нового ресурса.PUT/PATCH— полное / частичное обновление ресурса.DELETE— удаление ресурса.
-
Ресурсо-ориентированный подход. URL должны идентифицировать ресурсы, а не действия. Например,
GET /users/123(получить пользователя), а неGET /getUser?id=123. -
Использование стандартных кодов состояния HTTP. Ответ сервера должен содержать корректный код, отражающий результат операции:
200 OK— успешный запрос.201 Created— ресурс успешно создан.400 Bad Request— ошибка в запросе клиента (например, невалидные данные).404 Not Found— ресурс не найден.500 Internal Server Error— ошибка на сервере.
-
Версионирование. Для обеспечения обратной совместимости API следует версионировать, обычно через URL (
/api/v1/users). -
Безопасность. Использование HTTPS, а также механизмов аутентификации (например, JWT, OAuth 2.0) и авторизации.
-
Документация. API должен быть хорошо документирован. Стандартом де-факто является спецификация OpenAPI (Swagger).
Пример (FastAPI):
from fastapi import FastAPI, status
from pydantic import BaseModel
app = FastAPI()
class User(BaseModel):
username: str
email: str
# POST /api/v1/users вернет статус 201 Created
@app.post("/api/v1/users", status_code=status.HTTP_201_CREATED)
def create_user(user: User):
# Логика сохранения пользователя в БД
db_user_id = 1 # Имитация ID из базы данных
return {"id": db_user_id, **user.dict()} Ответ 18+ 🔞
Давай я тебе расскажу, как эти ваши REST API делать, чтобы не было потом мучительно больно за бесцельно прожитые годы, блядь. Это ж не просто так, там целая философия, ёпта!
Смотри, первое и главное — единый интерфейс, сука. Это как алфавит, его все знают. Не выёбывайся, используй стандартные методы, которые тебе HTTP дал:
GET— это когда ты просто пришёл посмотреть, как там дела. Получить данные, короче.POST— это когда ты принёс что-то новенькое и хочешь это оставить. Создать ресурс.PUT/PATCH— это когда ты пришёл что-то исправить. Либо всё переписать (PUT), либо заплатку поставить (PATCH).DELETE— ну тут всё ясно, блядь. Удалил и нет проблем.
Второе — ресурсы, а не действия. Это очень важно, ёбушки-воробушки! Ты должен думать о вещах, а не о глаголах. URL должен быть как адрес дома, а не как инструкция к сборке мебели. Правильно: GET /users/123 (дай мне пользователя 123). Неправильно, пиздец как: GET /getUserByIdWithPostsAndComments?id=123&action=view. Это же бред собачий, сука!
Третье — коды ответа. Это твой способ общаться с клиентом без слов. Ты же не будешь на каждый чих писать роман в JSON? Поставил правильный код — и всё, человек понял.
200 OK— ну, окей, всё чётко.201 Created— я твою хуйню принял и даже записал, вот тебе ID.400 Bad Request— ты мне какую-то дичь прислал, переделывай.404 Not Found— искал, искал, нихуя не нашёл. Может, ты ошибся?500 Internal Server Error— а вот это уже я обосрался, прости, брат. Иди попей чаю, пока я разгребаю.
Четвёртое — версионирование. Это на случай, если ты через год такой: "О, а давайте я всё сломаю и перепишу по-новой, будет охуенно!". Чтобы старые клиенты не накрылись медным тазом, версию в путь засунул: /api/v1/users, /api/v2/users. И все довольны.
Пятое — безопасность, ёпта. Это не шутки. HTTPS — обязательно, иначе все твои пароли и токены будут гулять по сети, как голые по проспекту. А ещё кто кому что можно делать — аутентификация и авторизация. Без этого — пидары налетят и всё разворуют.
Шестое — документация. Если твой API никто не понимает, кроме тебя и твоего кота, то он нихуя не стоит. Де-факто стандарт — OpenAPI (Swagger). Написал схему — и у тебя сразу и документация человеческая, и даже интерфейс для тестирования. Красота!
Ну и вот тебе пример, как это выглядит в коде, на FastAPI. Блок кода не трогаю, как договаривались, он и так норм.
from fastapi import FastAPI, status
from pydantic import BaseModel
app = FastAPI()
class User(BaseModel):
username: str
email: str
# POST /api/v1/users вернет статус 201 Created
@app.post("/api/v1/users", status_code=status.HTTP_201_CREATED)
def create_user(user: User):
# Логика сохранения пользователя в БД
db_user_id = 1 # Имитация ID из базы данных
return {"id": db_user_id, **user.dict()}
Вот видишь? Красиво, понятно, по канону. Создал пользователя — сразу статус 201 отправил, а не просто 200. Мелочь, а приятно, и клиент понимает, что всё прошло именно так, как задумано. А не гадает, создалось там что или нет. Вот так и живём, блядь.