I have a REST API uploadFeed that uploads the user feed based on feedType (string value taken input as part of the request body) . Different feedtype provides a different pojo model in the request body altogether.
For e.g If the feedType is lets say "TYPE1", then the API's request-body should look like the following:
{
"feedType":"TYPE1",
"inputModel": {
"a": "somevalue"
"b" : "somevalue",
"c" : "somevalue",
}
}
if the feedType is lets say "TYPE2", then the API's request-body should look like the following:
{
"feedType":"TYPE2",
"inputModel": {
"x": "somevalue"
"y" : "somevalue",
"z" : "somevalue",
}
}
What would be best API Design for the uploadFeed API. I am thinking of having two possible solutions:
Solution Proposal-1: Have two different API endpoints.
API URI for feedType == Type1: /uploadFeed/feedType/{Type1}. Here the requestBody here shall be same as the one mentioned above for Type1
API URI for feedType == Type2: /uploadFeed/feedType/{Type2}. Here the requestBody here shall be same as the one mentioned above for Type2
Solution Proposal-2: Have one endpoint with both model present. For feedType as TYPE1, expected requestBody shall be
{
"feedType":"TYPE1",
"type1Model": {
"a": "somevalue"
"b" : "somevalue",
"c" : "somevalue",
},
"type2Model" : null
}
For feedType as TYPE2, expected requestBody shall be
{
"feedType":"TYPE1",
"type1Model" : null
"type2Model": {
"x": "somevalue"
"y" : "somevalue",
"z" : "somevalue",
},
}
Is there any other possible way. Please suggest the best solution possible (not necessarily out of these two).
While it may be tempting to either use an own endpoint for each type or even introduce special media types that define the supported fields, this somehow may lead to situations where a client expects that resources have a specific type, which they don't, and thus tightly couple to the schema, which may cause troubles if they change later on, which in a REST architecture can happen at any time.
As REST is de facto just a generalization of the concepts used in the browsable Web, the same techniques that can and are used on the Web should be taken in a REST architecture.
Thereby one of your main goals should always be that a server is teaching a client on how to achieve things. The Web does this through the help of HTML forms that not only teach a client on the supported and/or expected input data but also on the target URI to send the request to, the HTTP operation to use as well as the media-type to send a representation for, which is often implicitly given by application/x-www-form-urlencoded
. For JSON based representation formats hal-forms or ion could be helpful to achieve this.
The representation format exchanged should be as generic as possible but in the same regards as expressive as possible as well. If you look at HTML i.e. you can literally express anything in it though, after all, it is just a Web page. A Web page depicting your preferred car model or sports team is processed the same way as any other Web page and doesn't hint your Web client (browser) that the page returns specific data representing a car or a sports team though a human is able to recognize the data and associate such objects with it.
As an application (or computer in general) is hardly able to deduce such relations by themselves, a client should further be hinted on the purpose of the resource especially in regards to the current state a client fetched. Here, the usage of so called link-relation names is essential. They more or less represent annotations accompanying URIs that allow the URI to change over time without losing expressiveness. You might be familiar already with link relation names such as first
, prev
, self
, next
and last
which are pretty much self-explanatory in the context of paging, though such link relations may be used to hint a client that some related resource is expected to be requested next via prefecth
(think of a news page where a short teaser is given on an article and a server may hint a client that the full article is likely to be requested next and as such the client can already download the article in the back, put it in its cache and allow the client to retrieve that content even faster). Such link-relations, however, shouldn't come from nowhere as there can be literally put anything in there and clients should know what they express. As such link relation names should be standardized to gain widespread adoption or at least follow common practices as defined in Web linking, that assigns link relation names to a dedicated namespace to prevent name clashes.
In the end, as a server-side developer your primary goal is to implement some kind of state machine, or as Jim Webber (2011) called it Domain Application Protocol
, that a client just follows through, like ordering at Amazon or your preferred Web shop, where a client basically just follows the choices given by the server to progress through its task of buying certain items.