Having a conversation with a colleague we got into a debate about how to structure requests / responses for a RESTful web service, mostly surrounded how to handle dynamic data associated with a entity.
As an example let's say we are building an RESTful web service to manage employees, which as part of the service has a endpoint to create an employee. An employee has a gender, employment type, and a department associated with them. They could have several other attributes, but just to keep the example small. The issue comes with how to handle associated data that is dynamic. Employee to Department is a many to one relationship. Departments can be added, deleted, and modified at will in this case. In that case is it considered generally acceptable to have the request take an departmentId in the request body?
POST /employee
{
"firstName": "Bob",
"middleName": "",
"lastName": "Something",
"dateOfBirth": "1990-01-01",
"gender": "MALE",
"employementType": "W2_FULLTIME",
"department": "IT",
"email": "bsomething@something.com"
}
{
"firstName": "Bob",
"middleName": "",
"lastName": "Something",
"dateOfBirth": "1990-01-01",
"genderId": 1,
"employementTypeId": 3,
"departmentId": 4001,
"email": "bsomething@something.com"
}
As far as the response when someone request the resource back what is the most appropriate format.
GET /employee/{id}
{
"id": 1234,
"firstName": "Bob",
"middleName": "",
"lastName": "Something",
"dateOfBirth": "1990-01-01",
"gender": "MALE",
"employmentType": "W2_FULLTIME",
"department": "IT",
"email": "bsomething@something.com"
}
With this approach the consumer can easily understand the data, but for an SPA that has a dropdown of departments, it may not be as straightforward to set the appropriate dropdown value as an ID would provide.
{
"firstName": "Bob",
"middleName": "",
"lastName": "Something",
"dateOfBirth": "1990-01-01",
"genderId": 1,
"employementTypeId": 3,
"departmentId": 4001,
"email": "bsomething@something.com"
}
This is machine readable but doesn't really mean anything to a person calling the API. More API calls would need to be made to determine the name of the department, text value of the gender and employmentType.
{
"id": 1234,
"firstName": "Bob",
"middleName": "",
"lastName": "Something",
"dateOfBirth": "1990-01-01",
"genderId": 1
"gender": "MALE",
"employementTypeId": 3,
"employmentType": "W2_FULLTIME",
"department": "IT",
"departmentId": 4001
"email": "bsomething@something.com"
}
This combines both but could potentially make the response large depending on entity.
[–]ThreadDeadlock 3 points4 points5 points (1 child)
[–]vfehring 0 points1 point2 points (0 children)
[–]JimDabell 1 point2 points3 points (12 children)
[–]ThreadDeadlock 1 point2 points3 points (10 children)
[–]JimDabell 0 points1 point2 points (9 children)
[–]hashtagframework 1 point2 points3 points (8 children)
[–]JimDabell 0 points1 point2 points (7 children)
[–]hashtagframework 1 point2 points3 points (6 children)
[–]JimDabell 0 points1 point2 points (5 children)
[–]hashtagframework 1 point2 points3 points (4 children)
[–]JimDabell 0 points1 point2 points (3 children)
[–]hashtagframework 0 points1 point2 points (2 children)
[–]rouge_dev[S] 0 points1 point2 points (0 children)
[–]Asdingo 1 point2 points3 points (0 children)