Inheritance and Polymorphism in REST API Modeling

emft picture emft · Sep 7, 2017 · Viewed 8.5k times · Source

I have an object hierarchy that I want to expose through a REST API, and I want to discuss best practices. I have seen this question asked before (e.g. here at the end, here, here, and especially here), but never really any conclusions arrived at.

Suppose I have one base class, say Animal, and many different classes that inherit, say Antelope, Bird, ..., Zebra. Each kind of animal has unique attributes.

Which is better?

  1. One endpoint path, /animals. You send and receive slightly different bodies depending on kind. There is a type field to help parse.
  2. A separate endpoint path for each kind of animal, /animals/antelopes, /animals/birds, ..., /animals/zebras. Each endpoint would always accept and return a consistent body (but these bodies would be different from each other).

Answer

asg picture asg · Sep 7, 2017

I would go with option #1. Reason is: What if your list - Antelope, Bird, ..., Zebra is increased in future? You will end-up creating separate endpoints for every animal.

Assumption is that there are not much differences between payloads of /animals/antelopes and /animals/birds. If differences are more, then you will need to create separate endpoints for each payload.

If there are minor differences between payloads, I would suggest to add extra map containing key value pairs and these pairs are the values which are specific to that particular animal type.

As you have mentioned, extra map can be of type -

{
 'shared_animal_attribute_1': 'foo', 
 'shared_animal_attribute_n': 'bar', 
 'extra_attributes': 
     { 
         'antelopiness': 10
     }
}

You will need to extra processing logic of these attributes on the server side. This will reduce the pain of maintaining separate endpoints. If you have schema to validate, it's a hassle-free implementation.