Single v Multiple REST endpoint - rest

Were working on making legacy code (Java) accessible via a REST API (Java/Spring/JSON).
Essentially our legacy code has numerous command processor type classes (which take in commands) and serve data back to the caller. So we have numerous command processors with numerous methods in them. Each method is analogous to a GET/POST of data, i.e. getCustomer / getCustomers / addCustomer etc..
We discussed 2 options:
Option 1 - Create endpoints for every operation.
Option 2 - Create one single REST endpoint and pass in a generic payload. The JSON being passed in would have a "type" identifier which in the endpoint we could then "construct" the require object type
I think option #1 is a better design as it's much simpler and adheres more to REST. I don't like option #2 as the single endpoint is now actually like a fancy front controller or dispatcher and would then either contain a huge switch statement.
I'd be interested in seeing what you guys think, pros / cons.

Related

What is the RESTful way to design URL that returns parent of a child resource?

I am modeling blogging REST API which has resources Blog, Post and Comment with following URLs:
/api/blogs
/api/blogs/{blogId}
/api/blogs/{blogId}/posts
and I create separate endpoint for all Posts in and their Comment`s:
/api/posts
/api/posts/{postId}
/api/posts/{postId}/comments
Given that I have postId, what is the RESTful way to get Blog for a specific Post? I have three ideas:
1. /api/posts/{postId}/blog
2. /api/blogs/parent-of-post/{postId}
3. /api/blogs?postId={postId}
To me the 1. URL looks more "prettier" but the 2. option looks more "logical" since that endpoint (eg. /api/blogs/*) is generally for blogs resources.
The third option uses query string as parameter but the issue I have with it is that this endpoint would return different type of body depending on the parameter. Eg. without parameter /api/blogs returns a collection of Blog resources, while with parameter postId it would return just single instance of Blog. I am not sure if this is good thing to do (especially because I am using ASP.NET Core and C# which has strongly typed return objects, so implementation might be awkward).
what is the RESTful way to get Blog for a specific Post?
Real answer: anything you want.
REST doesn't care what spelling conventions you use for your resource identifiers. As long as your identifiers conform to the production rules described by RFC 3986, you are good to go.
/api/blogs?postId={postId}
This is a perfectly normal choice, and turns out to be a really convenient one when you want to use general purpose web browsers, because HTML forms already have standards that make it easy to create URI with this shape.
Your other two choices are fine; they lose a point for not being HTML form friendly, but it's still easy enough to describe these identifiers using a URI template.
The third option uses query string as parameter but the issue I have with it is that this endpoint would return different type of body depending on the parameter
General purpose API consumers do NOT assume that two resources are alike just because the spellings of their identifiers overlap each other.
Which is to say, from the outside, there is no implied relationship between
/api/blogs
/api/blogs/1
/api/blogs?postId=2
so the fact that they return different bodies really isn't going to be a surprise to a general purpose consumer.
Now, your routing framework may not support returning different types from the handlers for these resources (or, more likely, may not have any "nice" way to do the routing automatically), but that's an implementation detail deliberately hidden behind the REST API facade.
Similarly, the human beings that read your access log might prefer one spelling to another, to reduce their own cognitive load.

Should model of a request for a PUT method be the same class with the model of the response of the GET method?

In my app, the backend will use an endpoint to get and update data (with GET and PUT method). The exact same JSON schema is used for both operations. The question is, should I also use the same model for the update request body and the get response body for this or not? Can you tell me the pros and cons of either separating and combining them?
Thanks.
Should model of a request for a PUT method be the same class with the model of the response of the GET method?
See RFC 7231:
A successful PUT of a given representation would suggest that a subsequent GET on that same target resource will result in an equivalent representation being sent in a 200 (OK) response.
It is normal that the PUT request will have the same Media Type as a successful GET response for that target-uri.
HTTP defines the semantics of the messages, but doesn't constrain the implementation (see Fielding 2002).
That said, if GET and PUT are using representations that change for the same reason, then a common implementation is reasonable, so it will likely be easier to maintain your code when those two paths share the same underlying model.
what about the Single Responsibility Principle if it's the same class?
My answer is that the Single Responsibility Principle doesn't actually make your code better in this case, so you don't use it. There are different ways you can try to generalize that idea; one is that you are working with a data structure, not an "object". Another is that this information is crossing a boundary, and at the boundaries, applications are not object-oriented.
Expressing that idea somewhat differently: what you have here is a single responsibility (manage some in memory representation of the message), but two different roles; an outbound role for the GET scenario (where you need to be able to convert the message into bytes, describe the content-type, and so on), and an inbound role for the PUT scenario (where you need to extract units of information from the data structure).

General thoughts about one Rest Endpoint and two Consumers

Consider the following situation:
You have one Endpoint, for example ../api/Samples
All Samples have the Attributes: Name, App.
You have two Apps which will consume the Samples Endpoint
The First App (A1) wants all Samples.
The Second App (A2) wants only a Subset of the Samples. To be exact only the Samples which have 'A2' standing in the 'App' Attribute.
What is the most REST-conform and common sense way to realize this?
So far I thought of three ways:
Create two Endpoints: ../api/A1Samples and ../api/A2Samples
This seems like overhead. What if more Apps come later? The Controller must be duplicated even if most of the code is identical.
Send the App Type within the URL: ../api/Samples/A1 or A2
Would be easier to maintain if more Apps come later. But doesn't this reject the thought of REST?
Send the App Type within the Accept Header: ../api/Samples and in the Header: App-Type: A1 or A2
In my case it seems this isn't easy to implement in ASP.NET Core v1.1 but should be the most syntactically correct way.
Can someone approve or reject my thoughts? Maybe even extend the list or state the usually used solution for this case?
If one of the applications requires all samples, it could simply consume /api/Samples directly; for the other one, have an extensible way to specify filters (even if that is just a few GET parameters) - if this is really an "App" attribute that exists on the Sample object then ?App=A2 would make sense, if it is some other attribute then specify those attributes directly.
This is more REST-ful than your /Samples/A1 and /Samples/A2 idea because it directly specifies the attribute being queried for (A1 doesn't use ?App=A1 because as you said Application 1 consumes the entire list of sample objects) rather than knowledge of what application is querying it, any similarity is simply due to the (I suspect contrived) structure of the example.
REST isn't just about something as simple as "use path parameters in all cases" - filtering a result list is a clear case for using query parameters instead.

How to define transforms on a resource in a REST way?

I'm designing a REST api, following best practices, including a form of hypermedia/hateoas. I'm using jsonapi for the design guidelines, which seems to be pretty complete.
Currently, I have a need for:
combining 2 resources in a response (a Resource A and a related Resource B). I do this using the Compound Documents - structure as specified in jsonapi. Or also commonly known as resource expansion
formatting the result of 1. in a specialized way so it can be readily consumed by a specialized client that expects said formatting.
My problem is with 2. How do I correctly represent this in a REST-way? It seems I may need a separate endpoint, but that wouldn't be 'RESTy', since that implies a separate resource, while it's just a transformation of the output of the same resource.
Any references on how to do this?
You could use a header or a query param to handle this.
When the client needs specific formatting, they could add an additional header to the request something like Format:Indented or something like http:\\myapp.com\resouces\myresource?format=indented
Or if the server is formatting and wants the client to know that the response is pre-formatted, the server could add a Format response header to notify the client that response is formatted.

How should I deal with object hierarchies in a RESTful API?

I am currently designing the API for an existing PHP application, and to this end am investigating REST as a sensible architectural approach.
I believe I have a reasonable grasp of the key concepts, but I'm struggling to find anybody that has tackled object hierarchies and REST.
Here's the problem...
In the [application] business object hierarchy we have:
Users
L which have one-to-many Channel objects
L which have one-to-many Member objects
In the application itself we use a lazy load approach to populate the User object with arrays of these objects as required. I believe in OO terms this is object aggregation, but I have seen various naming inconsistencies and do not care to start a war about the precise naming convention </flame war>.
For now, consider I have some loosely coupled objects that I may / may not populate depending on application need.
From a REST perspective, I am trying to ascertain what the approach should be. Here is my current thinking (considering GET only for the time being):
Option 1 - fully populate the objects:
GET api.example.com/user/{user_id}
Read the User object (resource) and return the User object with all possible Channel and Member objects pre-loaded and encoded (JSON or XML).
PROS: reduces the number of objects, no traversal of object hierarchies required
CONS: objects must be fully populated (expensive)
Option 2 - populate the primary object and include links to the other object resources:
GET api.example.com/user/{user_id}
Read the User object (resource) and return the User object User data populated and two lists.
Each list references the appropriate (sub) resource i.e.
api.example.com/channel/{channel_id}
api.example.com/member/{member_id}
I think this is close to (or exactly) the implications of hypermedia - the client can get the other resources if it wants (as long as I tag them sensibly).
PROS: client can choose to load the subordinates or otherwise, better separation of the objects as REST resources
CONS: further trip required to get the secondary resources
Option 3 - enable recursive retrieves
GET api.example.com/user/{user_id}
Read the User object and include links to lists of the sub-objects i.e.
api.example.com/user/{user_id}/channels
api.example.com/user/{user_id}/members
the /channels call would return a list of channel resources in the form (as above):
api.example.com/channel/{channel_id}
PROS: primary resources expose where to go to get the subordinates but not what they are (more RESTful?), no requirement to get the subordinates up front, the subordinate list generators (/channels and /members) provide interfaces (method like) making the response more service like.
CONS: three calls now required to fully populate the object
Option 4 - (re)consider the object design for REST
I am re-using the [existing] application object hierarchy and trying to apply it to REST - or perhaps more directly, provide an API interface to it.
Perhaps the REST object hierarchy should be different, or perhaps the new RESTful thinking is exposing limitations of the existing object design.
Any thoughts on the above welcomed.
There's no reason not to combine these.
api.example.com/user/{user_id} – return a user representation
api.example.com/channel/{channel_id} – return a channel representation
api.example.com/user/{user_id}/channels – return a list of channel representations
api.example.com/user/{user_id}/channel_list – return a list of channel ids (or links to their full representations, using the above links)
When in doubt, think about how you would display the data to a human user without "API" concerns: a user wants both index pages ({user_id}/channel_list) and full views ({user_id}/channels).
Once you have that, just support JSON instead of (or in addition to) HTML as the representation format, and you have REST.
The best advice I can give is to try and avoid thinking about your REST api as exposing your objects. The resources you create should support the use cases you need. If necessary you might create resources for all three options:
api.example.com/completeuser/{id}
api.example.com/linkeduser/{id}
api.example.com/lightweightuser/{id}
Obviously my names are a bit goofy, but it really doesn't matter what you call them. The idea is that you use the REST api to present data in the most logical way for the particular usage scenario. If there are multiple scenarios, create multiple resources, if necessary. I like to think of my resources more like UI models rather than business entities.
I would recommend Restful Obects which is standards for exposing domain model's restful
The idea of Restful Objects is to provide a standard, generic RESTful interface for domain object models, exposing representations of their structure using JSON and enabling interactions with domain object instances using HTTP GET, POST, PUT and DELETE.
According to the standard, the URIs will be like:
api.example.com/object/user/31
api.example.com/object/user/31/properties/username
api.example.com/object/user/31/collections/channels
api.example.com/object/user/31/collections/members
api.example.com/object/user/31/actions/someFunction
api.example.com/object/user/31/actions/someFunction/invoke
There are also other resources
api.example.com/services
api.example.com/domain-types
The specification defines a few primary representations:
object (which represents any domain object or service)
list (of links to other objects)
property
collection
action
action result (typically containing either an object or a list, or just feedback messages)
and also a small number of secondary representations such as home, and user
This is interesting as you’ll see that representations are fully self-describing, opening up the possibility of generic viewers to be implemented if required.
Alternatively, the representations can be consumed directly by a bespoke application.
Here's my conclusions from many hours searching and with input from the responders here:
Where I have an object that is effectively a multi-part object, I need to treat that as a single resource. Thus if I GET the object, all the sub-ordinates should be present. This is required in order that the resource is cacheable. If I part load the object (and provide an ETag stamp) then other requestors may receive a partial object when they expected a full one. Conclude - objects should be fully populated if they are being made available as resources.
Associated object relationships should be made available as links to other (primary) resources. In this way the objects are discoverable by traversing the API.
Also, the object hierarchy that made sense for main application site may appear not be what you need to act in RESTful manner, but is more likely revealing problems with the existing hierarchy. Having said this the API may require more specialised use cases than had been previously envisaged, and specialised resources may be required.
Hope that helps someone