Как я могу определить мой REST API?
У меня есть 3 модели: турнир, чемпионат и конкурент:
- Турнир имеет много чемпионатов;
- Чемпионат принадлежит турниру;
- У чемпионата много конкурентов.
Итак, чтобы перечислить всех участников всех чемпионатов, URL-адрес:
GET https://base.com/tournament/{slug}/competitors
но чтобы добавить конкурента, это связано с чемпионатом так:
POST https://base.com/championships/{id}/competitors
Это нормально, что для одной и той же модели два глагола (GET и POST) имеют разные URI? Иначе как мне поступить?
Я упал, как делает:
POST https://base.com/tournaments/{slug}/championships/{id}/competitors
не имеет обязательного поля.
2 ответа
Это нормально, что для одной и той же модели два глагола (
GET
а такжеPOST
) имеет разные URI?
Это может вызвать путаницу у потребителей API, поэтому я советую вам использовать тот же URI.
Имейте в виду, что архитектурный стиль REST, описанный в главе 5 диссертации Роя Т. Филдинга, определяет набор ограничений для приложений, построенных на основе такой архитектуры. Но это ничего не говорит о том, какими должны быть URI.
Примеры, показанные в популярной статье, написанной Мартином Фаулером, объясняющей модель, определенную Леонардом Ричардсоном, предлагают структуру URI, которая выглядит дружественной и легкой для чтения. Хотя это может быть желательно, это не обязательно для приложений REST.
Есть много подходящих подходов. Если конкурент требует наличия чемпионата, а чемпионат требует наличия турнира, вы можете выразить такую иерархию, используя:
/tournaments/{slug}
/tournaments/{slug}/championships/{id}
/tournaments/{slug}/championships/{id}/competitors/{id}
Но последний URI может считаться слишком длинным и его трудно запомнить. Таким образом, вы можете просто разделить его, тогда вам не нужно отправлять много параметров:
/tournaments/{slug}
/championships/{id}
/competitors/{id}
Если вам нужно выполнить какую-либо фильтрацию, вы можете использовать параметры запроса. Например:
/championships/{id}?tournament={slug}
Напоминание: REST не волнует, какое правописание вы используете для своего URI
Это нормально, что для одной и той же модели два глагола (GET и POST) имеют разные URI? Иначе как мне поступить?
Это нормально, но с этим связаны определенные расходы.
Давайте рассмотрим, что сказал Филдинг (2008)
REST предназначен для долгоживущих сетевых приложений, которые охватывают несколько организаций. Интерфейс REST спроектирован так, чтобы быть эффективным для передачи крупномасштабных гипермедиа-данных, оптимизируя для общего случая Интернета, но в результате получая интерфейс, который не является оптимальным для других форм архитектурного взаимодействия.
Одним из стилей репликации, который Филдинг определяет в своей диссертации, является кеш; он добавляет этот стиль к своему определению REST
Чтобы повысить эффективность сети, мы добавляем ограничения кэша, чтобы сформировать стиль client-cache-stateless-server.... Ограничения кэша требуют, чтобы данные в ответе на запрос неявно или явно помечались как кешируемые или не кешируемые. Если ответ кешируется, клиентскому кешу предоставляется право повторно использовать эти данные ответа для последующих эквивалентных запросов.
В HTTP семантика кэширования определена в RFC 7234; Раздел 4.4 описывает недействительность.
Кэш ДОЛЖЕН сделать недействительным действующий URI запроса (раздел 5.5 [RFC7230]), а также URI в полях заголовка ответа Location и Content-Location (если имеется), когда в ответ на небезопасный метод запроса.
Это означает, что связь, проходящая через универсальных клиентов, которые ничего не знают о специфике ваших протоколов, может сделать недействительной их локальную копию устаревших представлений на основе метаданных в запросе и ответе.
(Это было более сложным делом в прошлом, когда мы не шифровали весь трафик; но это все еще относится к (а) локальному кешу клиента и (б) обратному прокси-серверу кэширования, расположенному перед моделью домена).
Что касается REST, то URI непрозрачны; нет фундаментальной связи между
/A
/A/B
/A/B/C
/A/B/D
/A/E
Так что, если кэши видят, что /A/B
должны быть аннулированы, они могут сделать это, но они не будут делать ничего с другим URI.
Для PUT, DELETE, PATCH - семантика этих методов очень специфична для эффективного URI запроса.
Если вы примените тот же подход к POST, то вы получите кеш аннулирования "бесплатно".
Прогуливаясь по простому примеру; представьте веб-сайт, где мы имеем
GET /superCoolResource
GET /superCoolResource/editForm
Мы хотим вызвать некоторые изменения в /superCoolResource
, поэтому мы загружаем форму редактирования и отправляем ее....
POST ...?
Если мы отправим /superCoolResource/editForm
затем мы говорим клиенту, что кэшированная копия формы должна быть перезагружена, если процедура POST прошла успешно. Но это, вероятно, не то, что мы хотим - более вероятно, что форма остается прежней, и /superCoolResource - это то, что меняется. Это означает, что мы, вероятно, хотим сделать /superCoolResource
целевой URI
GET /superCoolResource/editForm
200 OK
... <form action="/superCoolResource" method="POST"> ....
и волшебным образом кеш клиента, кеш сервера источника и любые промежуточные кеши, которые доступны для диалога, знают, что при успешной проверке POST они удаляют свою старую копию /superCoolResource.