I'm a newbie both in SOAP and REST programming.
In SOAP the structure and the fields of the entities being exchanged
are always well and unambiguously documented in the WSDL.
I think the same does not happen in REST.
How is the developer of the REST API supposed to
document the structure and all the fields of the JSON objects, representing the entities being exchanged?
REST and SOAP can't be compared directly, as they are very different things. You can implement REST over SOAP if you want, but not the opposite. I recommend reading this answer.
In RESTful APIs you are supposed to document your media-types properly and let the interaction be driven by the underlying protocol, but don't look for that in most of the HTTP APIs that call themselves REST. They are using the term as a buzzword and often do the opposite of that, documenting the protocol instead of the media-types.
For instance, if you have an User resource, you are supposed to have a proper media-type for it in a format like JSON or XML that looks like application/vnd.mycompany.user.v1+json, and your documentation should describe what this JSON document looks like so the client knows what to expect. This doesn't have to be as strict as a WSDL. In fact, it can be a human readable documentation like you would do for documenting a class API or something like that.
The client can say what media-types he is prepared to accept with the Accept header. For instance, if a client wants the v1 representation in JSON, he can use something like:
GET /users/xyz
Accept: application/vnd.mycompany.user.v1+json
If he wants the v2 representation in XML, he can use something like:
GET /users/xyz
Accept: application/vnd.mycompany.user.v2+xml
And if he simply wants JSON and will let the server decide what to do, he can use a generic media-type and figure out what the server threw at him by checking the Content-Type response header.
GET /users/xyz
Accept: application/json
However, keep in mind that most of the so called REST APIs you'll find don't use custom media-types like this. Instead, they use the same generic media-types like application/json and application/xml everywhere. That means the clients have to identify resources through URI semantics and relations, and that's not REST at all. I'm not saying it's wrong, it's simple and works for many problems, but it's not REST and it doesn't solve the same kind of problems REST really intends to solve.
REST does not establish or recommend a way for you to structure your data. It's only meant to make it easy for anyone to figure out which methods and entities your API supports. You don't even necessarily need to output JSON in your REST API.
Related
I have been working Rest and json using spring framework.
I have got couple of doubts.
1)Is http transferring data in the form of json can be called Rest.I know http is protocol and Rest is architectural style?
2)Can any application (url) that accepts data in the form of json(sent from any client) called Rest?
2)why soap protocal is using http under the hood?
ReST is an architectural style which is completely independent of either HTTP or JSON. ReST really only talks about modelling a domain as a set of 'resources'. Any resource has a unique identifier which distinguishes it from other resources. Clients interact with resources using a common protocol and resources are created / modified / deleted through manipulating their representations.
HTTP and JSON are both aspects of specific implementations of a ReSTful architecture. HTTP is a good transport mechanism for ReSTful applications, providing a common API in the form of HTTP's set of verbs - GET, PUT, POST, DELETE. JSON is a good document transfer format and so is often used to implement the 'representation' aspect of ReST, but ReSTful applications can use other document formats if they choose - you can find ReSTful applications which use XML, JPEG, AVI, MP3, ...
Neither HTTP nor JSON is specifically ReSTful and its entirely possible to find HTTP applications using JSON which are not ReSTful at all. Similarly, not every ReSTful application will use JSON or HTTP (although I've never seen a real application in the wild which doesn't use HTTP/HTTPS).
Rest is not all about JSON, you have also the verbs GET, POST, PUT, DELETE and the http code for your answers which are involved.
If you post JSON for every action then it's not restful
In REST everything is a resource.
HTTP is an application layer. It's has nothing really with REST concept. You see a webpage via http and this is not REST at all. So SOAP can also use http.
HTTP is not bind to REST but REST is bind to HTTP
As stated in other comments, RESTful is an architecture, but not a language or coding paradigm.
RESTful:
Something anti-REST would be JSON-RPC (https://github.com/ethereum/wiki/wiki/JSON-RPC). The Framework is a Remote Procedure Call Lib. JSON-RPC would definitely not be RESTful since the RPC layer maps urls to functions (i.e. verbs) rather than particular resources (i.e. nouns). So rather than POSTing to some resource, you are calling a method, yet JSON as the format to serialize the data. There are tradeoffs to each. It just so happens RESTful APIs are very common for public ones as many believe documentation can be clearer to outsiders.
JSON:
On the other hand, one could develop a RESTful architecture and not use JSON. There are many serialization libs, each with tradeoffs such as compression and schema-less vs something closer to type safety. Examples besides JSON would include MessagePack and Google's ProtoBufs. Of coarse, you could even use XML, although uncommon with RESTful APIs. JSON is used a lot in public APIs since pretty much any language can do JSON serialization with low 3rd party over head (i.e. not importing specific libs)
I am currently trying to build a REST endpoint whereby an authenticated user can download a PDF. In researching the proper way to do this, I have mostly seen that JSON or XML are the proper response bodies to give. However, this site explains that the response can be something other than JSON as long as it's some human-readable document.
So, is it ever okay for a REST API to return application/pdf as the response type instead of application/json or application/xml?
Yes, definitely, a RESTful API can return whatever it wants. There is no constraint to be human-readable (although I think the linked article tries to argue exactly the opposite). Just think of the Web, which is REST-based, returning images, movies, sometimes even runnable code.
There are however some constraints. Any representation returned should be 'self-contained', meaning it has to has every piece of information necessary for the client to make sense of it. In this case, it would basically mean to just set the type 'application/pdf' properly on the response.
I am trying to stick to the Restful design pattern for both JSON and HTML. My issue is the design for creating a new resource (amongst others, but this is the gist of the issue). IE:
JSON – POST to /resource creates a new resource.
JSON – GET to /resource returns a list of resources.
JSON – GET to /resource/{id} returns a resource.
HTML – POST to /resource creates a new resource.
HTML – GET to /resource returns a list of resources.
HTML – GET to /resource/{id} returns a resource.
All good so far – but I need a HTML form to actually create the data to send to the HTML POST. Obviously POST and GET already do things. I could use one of the below to return the HTML form:
HTML – GET to /resource?CREATE
HTML - GET to /resource?action=CREATE
HTML – GET to /resources/CREATE
But they seem like a kludge and not that intuitive.
Any thoughts or ideas?
EDIT - See my answer to my question below. At present this is (I consider) the best option.
I would indeed use something like /resources/create. If you want to allow for non-numeric identifiers, then this will not work. In that case you can identify a resource with a prefix, such as /resources/resource-{id} and then you can still use /resources/create.
I found this blog post really helpful to make URI scheme decisions: http://blog.2partsmagic.com/restful-uri-design/
In fact, you should leverage content negotiation (CONNEG) when you want to handle several formats within RESTful services.
I mean:
Set the Content-Type header to specify the type of sent data
Set the Accept header to specify the type of data you want to receive
The server resources should leverage these hints to make the appropriate data conversion.
In the case of JSON, the content type would be obviously application/json. For HTML form, you should leverage the content type application/x-www-form-urlencoded (or multipart/form-data if you want to upload files as well). See the specification for more details.
Otherwise, you shouldn't use action in URL since it's not really RESTful. The HTTP verb should determine the action to do on the resource. I mean, to create a resource, the POST method should be used. The GET method aims to retrieve the state of a resource.
For more details, you could have a look at this blog post:
Designing a Web API (i.e. RESTful service).
I have an answer. I'll use standard RESTful POST from a HTML page, but when I have no form parameters sent and my accept header is text/html, I'll send a HTML form to the requestor. Keeps RESTful URI design and allows a clean HTML form + process (2 step).
HTML - POST - /resources (with no form attributes) generates a HTML form
HTML - POST - /resources (with form attributes) adds a resource
JSON - POST - /resources (with form attributes) adds a resource
OK, it's not "strictly" RESTful as I'm POSTing but not creating a new resource so in theory I should use a GET for that, but it's the best of a mismatched design.
If anyone can provide a better solution, I'm still all ears :-)
I'd rather add and endpoint called /templates/ that returns a template/form/whatever you need for given action. It also seems that the server should be unaware of such form existence. It can accept or reject a request and it's client job to submit it in an appropriate format.
I guess that you mix processing the view with preparing RESTful endpoints. The backend site should be completely unaware of the fact that some sort of view/form is required. It's client job to prepare such form.
We're having a bit of a discussion on the subject of posting data to a REST endpoint. Since the objects are quite complex, the easiest solution is to simply serialize them as JSON and send this in the request body.
Now the question is this: Is this kosher? Or should the JSON be set as a form parameter like data=[JSON]? Or is sending of JSON in the request body just frowned upon for forcing the clients using the application, to send their data via JavaScript instead of letting the browser package it up as application/x-www-form-urlencoded?
I know all three options work. But which are OK? Or at least recommended?
I'd say that both methods will work well
it's important that you stay consistent across your APIs. The option I would personally choose is simply sending the content as application/json.
POST doesn't force you to use application/x-www-form-urlencoded - it's simply something that's used a lot because it's what webbrowsers use.
There is nothing wrong about sending it directly as serialized JSON, for example google does this by default in it's volley library (which obviously is their recommended REST library for android).
If fact, there are plenty of questions on SO about how not to use JSON, but rather perform "normal" POST requests with volley. Which is a bit counter intuitive for beginners, having to overwrite it's base class' getParams() method.
But google having it's own REST library doing this by default, would be my indicator that it is OK.
You can use JSON as part of the request data as the OP had stated all three options work.
The OP needs to support JSON input as it had to support contain complex structural content. However, think of it this way... are you making a request to do something or are you just sending what is basically document data and you just happen to use the POST operation as the equivalent of create new entry.
That being the case, what you have is basically a resource endpoint with CRUDL semantics. Following up on that you're actually not limited to application/json but any type that the resource endpoint is supposed to handle.
For non-resource endpoints
I find that (specifically for JAX-RS) the application/x-www-urlencoded one is better.
Consistency with OAuth 2.0 and OpenID Connect, they use application/x-www-urlencoded.
Easier to annotate the individual fields using Swagger Annotations
Swagger provides more defaults.
Postman generates a nice form for you to fill out and makes things easier to test.
Examples of non-resource endpoints:
Authentication
Authorization
Simple Search (though I would use GET on this one)
Non-simple search where there are many criteria
Sending a message/document (though I would also consider multipart/form-data so I can pass meta data along with the content, but JAX-RS does not have a standard for this one Jersey and RestEasy have their own implementations)
The Sun Cloud API at http://kenai.com/projects/suncloudapis/pages/Home is a good example to follow for a RESTful API. True to RESTful principles, when you GET a resource you get no more nor less than a representation of that resource.
The Content-Type header in the response tells you exactly what the type of that resource is, for example application/vnd.com.sun.cloud.Snapshot+json. Sun has registered these mimetypes with the IANA.
How practical is this in general currently? Most API's I have seen have used the Content-Type of "application/json". This tells you that the response is JSON but nothing more about it. You have to have something in the JSON object, like a "type" property, to know what it is.
I'm designing a RESTful API (which will not be made public, therefore I wouldn't be registering mimetypes). I have been using RESTEasy and I find that even if I specify a complete mimetype, the Content-Type in the response header will be exactly what the Accept request header specified. If the request asks for "application/*+json" by default the response header will have "application/*+json". I can probably fix this by changing the header before the response goes out, but should I try to do that? Or should the response have a wildcard just like the request did?
Or should I just serve up "application/json" like most APIs seem to do?
Additional thoughts added later:
Another way of stating the question is: Should I use HTTP as the protocol, or should I use HTTP only as a transport mechanism to wrap my own protocol?
To use HTTP as the protocol, the entity body of the response contains the representation of the object requested (or the representation of an error message object), the "Content-Type" header contains the exact type of the object, and the "Status" header contains a success or error code.
To use HTTP as merely a transport mechanism, the "Status" header is always set to 200 OK, the "Content-Type" is something generic like "application/json", and the entity body contains something that itself has an object, an object type, an error code and whatever else you want. If your own protocol is RESTful, then the whole scheme is RESTful. (HTTP is a RESTful protocol but not the only possible one.)
Your own protocol will be opaque to all the transport layers. If you use HTTP as the protocol, all the transport layers will understand it and may do things you don't want; for instance a browser will intercept a "401 Unauthorized" response and put up a login dialog, even if you want to handle it yourself.
I use my own vnd.mycompany.mymediatype+xml media types for many of my representations. On the client I dispatch to the appropriate controller class based on the media type of the returned representation. This really allows the server to control the behavior of my client application in response to the user following a link.
Personally, I believe that using application/xml and application/json are one of the worst choices you can make if you hoping to support REST clients. The only exception to this is when the client only uses downloaded code (like Javascript) to interpret the data.
Or should I just serve up "application/json" like most APIs seem to do?
I don't think so.
A media type is the only point of coupling between your RESTful web application and the clients that use it. The documentation of your media types is the documentation of your API. Your media types are the contract between your clients and your application. Eliminate the specific media type and you eliminate an important element that makes REST workable.
Sun has registered these mimetypes with the IANA.
Couldn't find any mention of that here. AFAIK, there is no requirement to actually register your custom media type with the IANA. The convention seems to be to use the inverted domain notation of application/vnd.com.example.app.foo+json, which prevents namespace conflicts. If and when your media type becomes stable and public, it might be a good idea, but there's no requirement. Could be wrong on this, though.
Will you get any value by specifying a complete mimetype? Would you do anything with the complete mimetype different than you would if the mimetype was application/json?
My 2 cents- If the API is not going to be made public, then I see no reason for a complete mimetype. A mimetype of application/json should be more than enough. You already know the type of json that the response is returning. If the API eventually becomes public, then worry about a complete mimetype... or just let people figure it out.