Метод REST для создания нового ресурса с помощью POST

  1. Я хочу создать новый ресурс с помощью POST в / users { «Name»: «Mr. Лес », «Возраст»: 29 }
  2. У меня нет ID в запросе.

  3. Сервер создаст новый ресурс с автоматически сгенерированным идентификатором (даже те же данные существуют с другим идентификатором, что он и должен делать), скажем 1234

  4. Новое местоположение ресурса / users / 1234 должно быть возвращено в ответе.

  5. Теперь я должен просто вернуть новый идентификатор в качестве возвращаемого значения в ответе или новый идентификатор, установленный во входном запросе, и вернуть всю сущность? { «Id»: 1234, «Name»: «Mr. Лес », «Возраст»: 29 }

  6. Кроме того, когда запрос попадает в POST / users, но уже имеет идентификатор, указанный на входе, нужно ли нам проверять, является ли он нулевым перед созданием нового? Каким будет код ответа Http в этом случае, когда идентификатор существует во входных данных?

1
0
270
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Я бы использовал spring hateoas (https://spring.io/projects/spring-hateoas) и создал бы такой объект:

public class User extends ResourceSupport {
    private Long id;
    private int age;
    private String name;
    //Setter and getter and eventually hashCode and equals
}

то в контроллере я бы использовал такой метод:

@RequestMapping(value = "/users", method = {RequestMethod.POST}, produces = "application/json")
public ResponseEntity<User> managePerson(@RequestBody User p)
{
  if (p.getId() != null)
  {
    //Update; in this case a 204 http status is enough and no content is required
   Return ResponseEntity.status(HttpStatus.NO_CONTENT).body(null);
  }
  else
  {
   //Save and return the saved objecty with the returned ID and set the new location
   p.add(new Link("/users/"+p.getId()));
   Return ResponseEntity.status(HttpStatus.OK).body(p);
  }

}

Зачем вам нужно расширять класс DTO User до ResourceSupport?

IndoKnight 23.06.2018 13:46

I do not have ID in the request.

Он вам НЕ нужен. Вы можете просто использовать для этого Db-SDK.

The new resource location /users/1234 has to be returned in the response

Лучше бы сделать это систему на основе гипермедиа HATEOS

Now, should I just return the new ID as return value in the response or the new ID set in the input request and return the whole entity? { “id” : 1234, “name” : “Mr. Woods”, “age” : 29 }

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

{
    "id": 1234,
    "name": "Mr.Woods",
    "age": 29,
    "address": "/1234/address",
    "some-param": "/path-to-the-resource"
}

Also, when a request hits POST /users but already have an ID provided in the input, do we need to validate for this being null before creating a new one?

В идеале вы должны проверить это, если вы следуете спецификациям HTTP. Публикация всегда должна приводить к созданию ресурса. однако это просто следование спецификации, ничто не останавливает вас, если вы хотите сделать свой POST идемпотентным

Спасибо, но ваш ответ не ответил на мой последний вопрос. Что такое Db-SDK?

IndoKnight 23.06.2018 13:46

Да, вам следует проверить это, если вы следуете спецификациям. Также вы можете использовать конкретный код ответа для того же, что и 400 Bad Request.

Yati Sawhney 23.06.2018 13:51

SDK просто ссылается на внешние зависимости (jar-файлы). Многие из них поддерживают @Id для генерации UUID при создании ресурса.

Yati Sawhney 23.06.2018 13:52
POST should always result in the creation of resource: серверу, получившему запрос POST, необязательно создавать новый ресурс. Согласно Технические характеристики запрос POST - это запрос на обработку полезной нагрузки в соответствии с семантикой серверов. Таким образом, сервер решает, создаст он его или нет. Однако, если он создает представление ресурса, он должен вернуть URI созданного ресурса в качестве заголовка местоположения.
Roman Vottner 23.06.2018 16:46
Ответ принят как подходящий

Now, should I just return the new ID as return value in the response or the new ID set in the input request and return the whole entity? { “id” : 1234, “name” : “Mr. Woods”, “age” : 29 }

Успешный запрос Rest POST не обязательно должен иметь тело ответа, в целом, если это точно те же данные, что и в запросе + созданный идентификатор. Ответ 201 Created, содержащий в location header URI созданного ресурса, кажется нормальным.

Это не означает, что запрещено указывать тело в ответе POST, просто вы должны устанавливать его только в том случае, если он добавляет некоторую добавленную стоимость для клиента. Например, предположим, что создание ресурса может изменить данные, предоставленные клиентом (очистка, вычисления и т. д. Для ...), может иметь смысл установить ресурс в теле ответа.

Also, when a request hits POST /users but already have an ID provided in the input, do we need to validate for this being null before creating a new one? What would be the Http response code in this case when an ID exists in the input?

Это зависит от того, как вы хотите, чтобы ваши службы Rest работали:

  • Либо вы решите, что обновление разрешено для POST: в этом случае, если ID - null, вы создаете ресурс, а если это не null, вы обновляете ресурс, и если все в порядке, вы можете вернуть 202 Accepted.
  • Или вы решите, что обновление с POST незаконно: в другом случае, если ID не null, вы вернете ответ с ошибкой, например 400 Bad Request.

Мне нравится твоя последняя мысль. Может ли идентификатор быть тем, который сгенерирован базой данных с использованием генератора порядковых номеров, такого как первичный ключ?

IndoKnight 23.06.2018 13:44

Конечно. Ресурс следует рассматривать как представление данных в хранилище вашей информационной системы. Поэтому, если вы сохраняете его в БД, имеет смысл использовать функции БД для генерации идентификаторов.

davidxxx 23.06.2018 13:47

благодарю за разъяснение

IndoKnight 23.06.2018 14:22

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