2

Given the following REST endpoints:

(GET, POST)  /api/v2/employer
(GET)        /api/v2/employer/{id}
(GET, POST)  /api/v2/employer/{id}/employees

Should a consumer of this API have the ability to POST a new employer resource that includes a list of employees? For example:

POST: /api/v2/employer

{
    employerName: "Bob's Plumbing",
    headquarters: "Des Moines, IA, US",
    industry: "plumbing",
    employees: [
        { firstName: "Bob", lastName: "Jones", dob: "1982-05-16" },
        { firstName: "Philip", lastName: "Jones", dob: "2001-03-12" },
        { firstName: "John", lastName: "Smith", dob: "1991-02-19" }
    ]
}

Or, should the consumer be required to break this into multiple calls?

POST: /api/v2/employer

{
    employerName: "Bob's Plumbing",
    headquarters: "Des Moines, IA, US",
    industry: "plumbing",
}

// ... the ID of the new employer is returned (for example, "5") ...

POST: /api/v2/employer/5/employees

{ firstName: "Bob", lastName: "Jones", dob: "1982-05-16" }

POST: /api/v2/employer/5/employees

{ firstName: "Philip", lastName: "Jones", dob: "2001-03-12" }

POST: /api/v2/employer/5/employees

{ firstName: "John", lastName: "Smith", dob: "1991-02-19" }
  • 1
    given theres not much difference between the two, maybe you could add some backstory to this question – Ewan Jun 8 '18 at 13:01
2

Should a consumer of this API have the ability to POST a new employer resource that includes a list of employees?

Heuristic: envision your API as a bunch of web pages.

Would it be reasonable to have one form, into which a consumer add entries into a list of employees, and then submit that form in a single request?

I don't know the details of your use case, so I can't say for certain. But I can offer the following suggestions

  • The fact that you are using URI spelling conventions that make it easier for human beings to understand your identifier semantics does not matter.

  • The fact that the message-body of your request is an application/json representation of data, rather than an application/x-www-form-urlencoded representation does not matter.

  • In HTTP, selecting the target URI for a POST is more about which resource you want the client to evict from its cache than it is about how your server is organizing its private data.

1

It depends on how your aggregates are organized. In your example above, Employer is an aggregate. If you are editing the list of pre-existing employees that belong to the employer, that should be persisted with the Employer update. i.e. the list of Employee IDs should be included in the Employer JSON and persisted as necessary.

You should not be creating new employees this way. In most systems, Employee would be a separate aggregate so I'll assume that's true here as well. In that case, you probably have an endpoint for Employee and new employees should be created/updated there.

If you created the Employees as part of the Employer update, they are treated as entities, not full aggregates, and so are validated in the context of an Employer. If you have business rules that force an Employee to have a mailing address, this rule may not be applied in the context of an Employer, but would be applied when saving the Employee by itself. You may be thinking that you can just validate the employees also, but validating objects the employer owns means you should validate the objects that employee owns, which means you should validate the objects that those own, etc.

BTW, Your example shows the two extremes of API calls, either a single one or many. If you use the Employee endpoint as described above, along with the multiple-creation ideas expressed here:

https://stackoverflow.com/questions/411462/restful-way-to-create-multiple-items-in-one-request?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

You can keep your API calls down to a maximum of 2.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.