Каковы основные принципы проектирования качественного Web API?

Ответ

Качественный Web API (чаще всего RESTful) строится на общепринятых принципах, которые обеспечивают его стабильность, предсказуемость и удобство использования.

  1. Единообразие интерфейса (Uniform Interface). Использование стандартных HTTP-методов для операций с ресурсами:

    • GET — получение данных.
    • POST — создание нового ресурса.
    • PUT / PATCH — полное / частичное обновление ресурса.
    • DELETE — удаление ресурса.
  2. Ресурсо-ориентированный подход. URL должны идентифицировать ресурсы, а не действия. Например, GET /users/123 (получить пользователя), а не GET /getUser?id=123.

  3. Использование стандартных кодов состояния HTTP. Ответ сервера должен содержать корректный код, отражающий результат операции:

    • 200 OK — успешный запрос.
    • 201 Created — ресурс успешно создан.
    • 400 Bad Request — ошибка в запросе клиента (например, невалидные данные).
    • 404 Not Found — ресурс не найден.
    • 500 Internal Server Error — ошибка на сервере.
  4. Версионирование. Для обеспечения обратной совместимости API следует версионировать, обычно через URL (/api/v1/users).

  5. Безопасность. Использование HTTPS, а также механизмов аутентификации (например, JWT, OAuth 2.0) и авторизации.

  6. Документация. 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. Мелочь, а приятно, и клиент понимает, что всё прошло именно так, как задумано. А не гадает, создалось там что или нет. Вот так и живём, блядь.