Skip to content

Instantly share code, notes, and snippets.

@revilon1991
Last active July 6, 2022 07:44
Show Gist options
  • Save revilon1991/15560ee72e0da7f16ac2f4d831619a4a to your computer and use it in GitHub Desktop.
Save revilon1991/15560ee72e0da7f16ac2f4d831619a4a to your computer and use it in GitHub Desktop.
REST API Recommendation

REST API

Схема доставки ресурса от клиента до бекенда.

  • В колонке result учитывается состояние модели полученное хендлером (не БД)
  • Required - означает, что поле должно фигурировать в запросе, иначе ошибка.
  • Default - если значение по умолчанию не было задано, оно рассматривается как null. api

Определения параметров в GET запросах

Есть три основных параметра, которые передаются в формате массива/значения

  • Фильтрация (filterList) - задаются критерии по которым 1 или более записей будет не включенно в результирующую выборку.
  • Группировка (groupByList) - это когда 2 или более записей схлопываются в одну строчку, а данные агрегируются(складываются/находится среднее значение/находится максимальное значение и тд)
  • Сортировка (sortByList) - у всего списка будет изменен порядок основываясь на одном или нескольких столбцов.
  • Другие параметры не входящие в вышеперечисленные критерии - Если случай не подходит ни под один из трех вышеописанных определений, мы используем именные параметры.Как правило это параметр, который меняет отображение и при этом его нельзя отнести к выше перечисленным критериям.
    • Например: Валюта (currency) - этим параметром можно задать в какой валюте нужно отобразить данные, при этом эти данные не схлопываются/не фильтруются/не задается сортировочное поле.

Формат передачи параметров

  • GET /api/user?filterList[fromCreatedAt]=1651056403&filterList[toCreatedAt]=1651066403
  • GET /api/user?groupByList[]=gender&groupByList[]=country
  • GET /api/user?sortByList[]=age&sortByList[]=name
  • GET /api/user?currency=EUR

Примечание:

  • Допускается именование параметра без приставки List, если параметр не подразумевает множественности.

Заголовки

Приветствуются следующие заголовки для запроса/ответа:

  • Accept - используется на GET запросах. В этом заголовке клиент сообщает серверу, какой формат ответа будет предпочтительнее, например в случае csv это будет text/csv, для json значение будет application/json.
  • Content-Location - используется на POST ответах в случае успешного создания ресурса. Предполагается, что в значении будет передан id ресурса, который однозначно его идентифицирует.
  • Content-Type - используется GET ответах. Указывает какой формат данных передается в body ответа. Как правило это application/json, но в случае, если был запрошен формат ответа csv он должен быть text/csv.
  • X-Meta-Count - используется GET ответах. Указывает сколько всего записей имеется для последующей пагинации. Основываясь на этом числе клиент формирует постраничную навигацию.
  • X-Meta-Next-Page-Token - используется GET ответах. Необходим для курсорной пагинации. Указывает токен, который нужно передать серверу для получения следующей страницы с ответами. Клиенту не требуется декодировать токен для его чтения и анализа, однако можно учитывать, что он должен хранить в себе.
    • Содержимое и свойства токена:
      • Формат base64
      • Может содержать в себе id последнего ресурса из текущего запроса, чтобы в следующем запросе добавить такое условие where id > base64decode(token)
      • Может содержать в себе кол-во записей, которые нужно пропустить перед выборкой, считается как limit+offset текущего запроса.
      • В токене не хранится конфигурация(фильтры, сортировки и тп) из запроса, поэтому, если конфигурация меняется, то выборка начинается с первой страницы.
  • Content-Disposition - используется GET ответах. Этим заголовком мы можем сообщить клиенту где будет находится контент ответа сформированный из полученного запроса. Как правило значение этого заголовка inline для json ответов, однако если был запрошен csv, то значение будет следующиим attachment; filename="list.csv"

HTTP коды ответов

Необходимо использовать коды ответов опираясь на результат ответа и официальный RFC. Однако есть несколько рекомендаций:

  • Если мы получили невалидное тело запроса и проведенная валидация не имеет прямого отношения к бизнес логике, то мы возвращаем 400 HTTP status code. Примеры:
    • Timestamp который содержит буквенные символы.
    • Отрицательное значение для максимальной суммы.
    • Несуществующая страна.
    • И тд.
  • Если мы получили невалидное тело запроса и проведенная валидация имеет прямое отношение к бизнес логике и как правило она проводится на Handler, то мы возвращает 200 HTTP status code, а в теле запроса код ошибки и причину, которая в человекопонятном формате может быть переданна клиенту. Примеры:
    • Сумма банковской операции не может быть задана, если банк корреспондент ее зафиксировал.
    • Максимальная процентная ставка была ограничена для указанной валюты.
    • Адресат не является резидентом страны отправителя.
    • И тд.
  • На ручке POST при успешном создании ресурса передаем 201 HTTP status code.
  • На ручке PUT/PATCH, если ничего не было измененно, то передаем 205 HTTP status code, что сообщает клиенту о том, что данные его запроса устарели и их нужно сбросить.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment