REST-объекты

Какова правильная структура RESTful, URL для обновления дочерних объектов?

Например, у меня есть сущность Вопрос. Вопрос может иметь много ответов. Ответы - это не просто строка, они имеют пользователя, pubDate и т. Д.

URL для создания объекта Вопрос выглядит так:

/questions/create

Каким будет правильный формат для создания ответа на конкретный вопрос? Может быть что-то вроде:

/questions/{questionId}/answers/create

Или они должны иметь свой собственный выделенный маршрут, например:

/answers/create?questionId={questionId}

Спасибо за любую помощь, которую вы, ребята, можете предоставить!

1 ответ

Решение

Вопреки распространенному мнению, REST на самом деле не относится к структуре URL. Фактически, должен быть только один "читаемый человеком"URL, все остальные обнаружены HATEOAS.

Кроме того, не должно быть никакого "URL для создания вопроса". Должен быть один (или несколько) контейнеров вопросов, и когда вы размещаете там POST, создаются новые сущности. Точно так же, когда у вас есть URL-адрес Вопроса (возвращаемый при создании, клиент не должен знать, какая у него "структура"), вы создаете там новые POST для создания ответов.

В вашем примере, после того, как вы выполните требуемую аутентификацию, GET для "корневого"URL-адреса может вернуть "основной" ресурс со всеми необходимыми контейнерами:

GET /api/
=> { "questions":"/api/questions/", .... }

GET /api/questions/
=> [{"name":"firstone", "href":"/api/questions/11"}, 
    {"name":"final", "href":"/api/questions/43"}]

GET /api/questions/101
=> {
    "name":"firstone", 
    "href":"/api/questions/11", 
    "text":"2+2", 
    "answers":[
        {"key":"A", "text":"23", "href":"/api/answers/15"},
        {"key":"B", "text":"3", "href":"/api/answers/34"},
        {"key":"C", "text":"4", "href":"/api/answers/7"}
    ]
}

добавить новый вопрос:

POST /api/questions/   {"name":"onemore", "text":"2^2"}
=> 201 Location: /api/questions/45   
data: {"name":"onemore", "text":"2^2", "href":"/api/questions/45"}

GET /api/questions/45
=> {"name":"onemore", "text":"2^2", "href":"/api/questions/45"}

добавить ответ:

POST /api/questions/45    {"key":"A", "text":"4.5"}
=> 201 Location: /api/answers/56
data: {"key":"A", "text":"4.5", "href":"/api/answers/56", "question":"/api/questions/45"}

изменить текст ответа:

PUT /api/answers/56   {"key":"A", "text":"4.8"}
=> 200
data: {"key":"A", "text":"4.5", "href":"/api/answers/56", "question":"/api/questions/45"}

Конечно, есть много вариантов, особенно о том, сколько "глубокой" информации возвращается, когда вы получаете контейнер. В этом примере, когда вы получаете вопрос, есть список ответов. С одной стороны, это может быть просто список URL-адресов, и клиент должен получить каждый из них, с другой стороны, это могут быть целые данные для каждого из них, поэтому у вас есть все, что вам нужно, с помощью одного запроса.

Как правило, вы должны выбрать баланс для каждого контейнера, могут быть некоторые "базовые" поля, которые полезно иметь с первого запроса, в то время как другие могут быть отложены.

Другие вопросы по тегам