'How to specify subtypes of some resource type in a RESTful API?

(Couldn't find a tutorial or clear description of this in guides like REST API Tutorial and StackOverflow's blog on REST API best practices, and a SO question on subtypes discusses another angle.)

How should we specify different subtypes of the same resource type in a REST API?

For example consider different kinds of contacts in a CRM application: B2C customers which are persons, B2B customers who are companies, and B2E persons which are employees of our own company.

I can think of two ways of specifying that in the URL path. The main distinction is how it affects the list of required/optional resource attributes in the documentation. Similarly, this oozes through in the code handling the API requests. The validation whether some attributes are allowed, required or optional likely differs between entities of different resource types.

Specify subtypes explicitly in the resource URL path

https://api.example.com/contacts/b2b/:id
https://api.example.com/contacts/b2c/:id
https://api.example.com/contacts/b2e/:id

or something like

https://api.example.com/b2b-contacts/:id
https://api.example.com/b2c-contacts/:id
https://api.example.com/b2e-contacts/:id\

The advantage is that the API contract can be defined very specifically, and tailored to each type of the resource. Some attributes are common (id,name,street,email,...) whereas other attributes are specific only to one type (coc, duns, vat-id, ... for B2B contacts, and employee-id, department, dob, ... for employees). The API documentation could clearly specify the list of allowed/required/optional attributes for each subtype/resource.

(Don't dive into the proper way to register company contacts or employees... it's just an example.)

Group different subtypes under the common resource in the URL path

https://api.example.com/contacts/:id
with the objects (resource state representations conforming to the REST parlance) specifying the subtype in one of the attributes being exchanged.

This is more generic and flexible, but the API documentation needs to clearly specify which attributes are required/optional for each contact type. type will be an attribute too.

So, in this case, the documentation is likely to list attributes like

Attribute Applicable for types Required
id All (or: B2B, B2C, B2E) Yes
name All Yes
email All No
contact-type All Yes
... ... ...
... ... ...
employee-id B2E Yes
dob B2E, B2C No
dept B2E No
... ... ...
coc B2B Yes
fax B2B, B2C No
... ... ...
ssn B2C Yes

(Again, don't critique the specifics and appropriateness of this CRM example. It's just an example. I know we shouldn't store a social security number commonly, and B2B customers typically contain/refer to a person as well.)

Question

What's the common way to handle this? How to document it, and how should attribute validations (allowed, required, optional) be handled?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source