Следует ввести объекты переноса данных для конечных точек RESTful соответствовать выходной объекты переноса данных?
Я работаю над RESTful API, и у меня возникли некоторые проблемы с тем, чтобы разобраться в процедуре подачи входных данных в API.
Допустим, у меня есть ресурс "Person", который можно извлечь следующим образом: api/person/{id}
и возвращает объект, подобный этому:
public class Person
{
public int Id { get; set; }
public string Surname { get; set; }
public string GivenName { get; set; }
public DateTime DateOfBirth { get; set; }
}
Если я хочу обновить этого человека, должен ли API ожидать полный экземпляр Person
, или допустимо использовать отдельный DTO?
Допустим, например, что DateOfBirth
нельзя изменить, считается ли это успокаивающим для примите это в качестве входных данных:
public class UpdatePersonDto
{
public string Surname { get; set; }
public string GivenName { get; set; }
}
Это будет означать, что я буду иметь эту конечную точку api/person/{id}
, возвращающую Person
при использовании GET
, Принимая в качестве входных данных UpdatePersonDto
при использовании PUT
. Это звучит неправильно для меня, но я не уверен, что я просто параноик.
Итак, я полагаю, что мой вопрос сводится к следующему: можно ли принять структуру данных на данной конечной точке ресурса, которая отличается от того, что эта конечная точка будет возвращать?
2 ответа:
Похоже, что все остальные единодушны в том, что при обновлении с использованием PUT один поставляет всю сущность для замены.
Программно, это будет работать, поставив /person / {id} принимающий вход, который за кулисами отображает UpdatePersonDTO вместо Person.
Единственная "проблема" может заключаться в том, что это действительно идет вразрез с общим ожиданием.Промежуточным решением может быть POST (или PUT) /person/{id}/mutables, которые могут принимать UpdatePersonDTO.
Edit: или parhaps более очевидно: PUT / person / {id} / name, который принимает аргумент PersonName, содержащий два поля.
Когда речь заходит о строгих правилах покоя (насколько такие правила вообще существуют:/), вы должны отправить всю сущность в
PUT
. Теперь вы можете:Лично я считаю, что лучший вариант-это 1 или 3. Чего я не предлагаю, так это вводить новые конечные точки, как это предлагает @morsor. Такие конечные точки всегда вносят беспорядок. Как правило, чем меньше конечных точек используется, тем лучше (чище, проще для понимания) API.
- молча игнорировать поля, которые не могут быть обновлены-рекомендуется в некоторых случаях, но должны быть задокументированы.
- вызовите исключение, если вы обнаружите, что полю, которое не может быть обновлено, было присвоено новое значение.
- вместо использования
PUT
, используйтеPATCH
, который может обновить группу полей, и вся сущность не является необходимой, например, только первый и фамилия может быть отправлена.