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-адресов, и клиент должен получить каждый из них, с другой стороны, это могут быть целые данные для каждого из них, поэтому у вас есть все, что вам нужно, с помощью одного запроса.
Как правило, вы должны выбрать баланс для каждого контейнера, могут быть некоторые "базовые" поля, которые полезно иметь с первого запроса, в то время как другие могут быть отложены.