Designing POST response body for different types of responses - rest

From my client application I make a POST call to a \validate end-point. This call is made to execute the controller on the server side and not to create any resource. In response, server can provide one of the two totally unrelated JSON objects. From the client, how do I know which of the two types I should use during deserialization? What is the clean way to do this?

There are multiple ways to do it.
Add some header to the http response to determine body type. Client should check header and use corresponding deserializer. This is a typical approach for webhooks API where you have single endpoint to process different event type. As an example, you could check AWS SNS API that uses x-amz-sns-message-type header to define response type.
As an alternative you could use special body format with some type field and payload that depends on this type.
{
"type: "Type",
"paylod": {
...
}
}
But from my opinion this approach is much harder to handle for the client and would required 2-step deserialization process.

Related

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).

Should I use GET or POST REST API Method?

I want to retrieve data about a bunch of resources. Let's say an Array of book id and the response is JSON Array of book objects. I want to send the request payload as JSON to the server.
Should I use GET and POST method?
Note:
I don't want to make multiple GET request for each book ID.
POST seems to be confusing as it is supposed to be used only when the request creates a resource or modifies the server state.
I want to retrieve data about a bunch of resources. Let's say an Array of book id and the response is JSON Array of book objects.
If you are thinking about passing the array of book id as the message body of the HTTP Request, then GET is a bad idea.
A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.
You should use POST instead
POST seems to be confusing as it is supposed to be used only when the request creates a resource or modifies the server state.
That's not quite right. POST can be used for anything -- see GraphQL or SOAP. But what you give up by using POST is the ability of intermediate components to participate in the conversation.
For example, for cases that are effectively read-only, you would like to use a safe method, because that allows pre-caching optimization, and automated retry of lost responses on an unreliable network. POST doesn't have extra semantic constraints, so you lose out.
What HTTP really wants is that you GET using the URI; this can be done in one of two relatively straightforward ways:
POST the ids to the server, to create a new resource (meaning that the server retains for itself a copy of the list of ids), and receive a new resource identifier back in exchange. Then GET using this new identifier any time you want to know the current representation of the results.
Encode the information you need into the URI itself. Most commonly, this is done using the query part of the URI, although that isn't strictly necessary. The downside here is that if the URI encoded representation of the array of ids is very long, you may have trouble with some implementations that enforce arbitrary URI limits.
There aren't always great answers:
The REST interface is designed to be efficient for large-grain hypermedia data transfer, optimizing for the common case of the Web, but resulting in an interface that is not optimal for other forms of architectural interaction.
If I understand correctly, you want to get a list of all of the items in a list, in one pull. This would be possible using GET, as REST returns the JSON it can by default be up to 100 items, and you can get more items if needed by specifying $top.
As far as writing back or to the server, POST would be what your looking for, this to my understanding would need to be one for one.
you are going to use a GET-Request and put your request-data (book-id array) in the data-section of your ajax (or whatever you're going to use) request. See How to pass parameters in GET requests with jQuery

Modify Rest POST request behavior with query String

I have a resource which basically represents a number. I have two possible updates for this number: Set the number to a specific value or add a value to it. Now I'm confused if I can use the query string part of the URL to specify the desired behavior.
Something like this:
/resource/{id}/?mode=add
/resource/{id}/?mode=set
Or is there an alternative way two represent to update strategies for a rest resource?
An Alternative would be to extend the request body with this information but this since strange, since the request data should contain the data and not "meta information" for the request itself - as far as I understand REST apis.
The project is an ordinary angularjs (client) and java (server) project.

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.

RESTFul service and "GetCapabilities"

I'm writing a REST service which is dealing with SomeKindOfResource stored in a database.
Don't ask me why (don't!) but for some reasons, the corresponding underlying table has a variable number of columns. That's the way it is and I can't change it.
Therefore, when I issue a GET /SomeKindOfResources/{id}, my DTO (later on serialized to JSON) might then contain a variable number of "fields". I know how to handle the dynamic object / serialization parts. My question is more on the philosophy side of things.
Let's say my client wants to know what will be the list of fields returned by a call to GET /SomeKindOfResources/{id} because, for example, that list determines what can be used, later-on, to filter out a list of SomeKindOfResources. Basically, I need something resembling a "GetCapability".
How would you deal with such a scenario in a RESTful way?
If I understand your requirement correctly, you want to return a metadata like response for a specific object (i.e. by Id) that has dynamic fields, so your client knows the field types it will receive when requesting that object.
Just a word of caution: A dynamic DTO isn't RESTful. The point of a DTO is that it is an agreed contract. It shouldn't change and as such there isn't a RESTful rule to handle your use case.
If you were to implement this, these are three possible approaches.
Metadata Route:
Create a new route, in your service, as this scenario isn't covered by the standard ServiceStack MetadataFeature, as it only works with static DTOs. So create something like this:
[Route("/SomeKindOfResources/{Id}/metadata", "GET"]
Then you would want the response to that route to describe the fields to your client. This is where it gets cloudy. The MetaDataFeature uses XSD to describe your standard DTOs, you could write your action to produce an XSD response which would describe your fields, based on your database lookup of available fields. But then will your client know how to parse XSD? As your use isn't standard, and the client can't be expected to handle it in a RESTful way, so you may just want to use a simple response type, like a Dictionary<string,Type>() essentially just returning field name, and underlying type. This will work fine for simple built in types, like string, int, bool etc, but custom class scenarios will be harder to handle, such as List<MySpecialType>.
Pseudo client code:
var fieldMetaData = client.get("/SomeKindOfResources/123/metadata");
var result = client.get("/SomeKingOfResources/123");
Example XSD Metadata Response.
OPTIONS header:
However you may wish to consider using the OPTIONS verb instead of a GET request to another prepended with /metadata, as recommended by RFC2616 ยง9.
This method allows the client to determine the options and/or requirements associated with a resource ... without implying a resource action or initiating a resource retrieval.
Pseudo client code:
var fieldMetaData = client.options("/SomeKindOfResources/123");
var result = client.get("/SomeKindOfResources/123");
But remember OPTIONS in REST is typically used for setting up CORS.
ServiceStack JSON __type response:
When ServiceStack returns JSON, you can tell the ServiceStack.Text serializer to include the return type information in a property call __type. Although this may not be easy for your clients to interpret, and it also applies globally to all JSON responses, so wouldn't be limited to just that action. In your configure method add:
JsConfig.IncludeTypeInfo = true;
Pseudo client code:
var result = client.get("/SomeKingOfResources/123");
var typeInformation = result.__type;