In JAX-WS usually the response object will be a string or an XML format.
Can we have 2 kinds of response objects.
I mean, based on flag, XML or JSON as response output?
Is there any Objectwrapper kind of solution?
Am new to JAX-WS ,So am totally clueless. Thanks
According to Wikipedia here, you don't need XML to represent the SOAP message. But it looks like you will need SOAP bindings that support JSON. Reading the description in that article makes it sound like you can't just set a flag and have the response format change based on that.
If you want something where you set a flag to generate a different response format, consider a REST architecture instead. In REST, you would send a different Accept header to specify the format of the response you want. There wouldn't need to be a flag in your application specific data to handle the data format since that's more of metadata concern anyways.
Related
Im currently working on a more or less RESTful webservice, a type of content api for my companys articles. We currently have a resource for getting all the content of a specific article
http://api.com/content/articles/{id}
will return a full set of article data of the given article id.
Currently we control alot of the article's business logic becasue we only serve a native-app from the webservice. This means we convert tags, links, images and so on in the body text of the article, into a protocol the native-app can understand. Same with alot of different attributes and data on the article, we will transform and modify its original (web) state into a state that the native-app will understand.
fx. img tags will be converted from a normal <img src="http://source.com"/> into a <img src="inline-image//{imageId}"/> tag, samt goes for anchor tags etc.
Now i have to implement a resource that can return the articles data in a new representation
I'm puzzled over how best to do this.
I could just implement a completely new resource, on a different url like: content/articles/web/{id} and move the old one to content/article/app/{id}
I could also specify in my documentation of the resource, that a client should always specify a specific request header maybe the Accept header for the webservice to determine which representation of the article to return.
I could also just use the original url, and use a url parameter like .../{id}/?version=app or .../{id}/?version=web
What would you guys reckon would be the best option? My personal preference lean towards option 1, simply because i think its easier to understand for clients of the webservice.
Regards, Martin.
EDIT:
I have chosen to go with option 1. Thanks for helping out and giving pros and cons. :)
I would choose #1. If you need to preserve the existing URLS you could add a new one content/articles/{id}/native or content/native-articles/{id}/. Both are REST enough.
Working with paths make content more easily cacheable than both header or param options. Using Content-Type overcomplicates the service especially when both are returning JSON.
Use the HTTP concept of Content Negotiation. Use the Accept header with vendor types.
Get the articles in the native representation:
GET /api.com/content/articles/1234
Accept: application/vnd.com.exmaple.article.native+json
Get the articles in the original representation:
GET /api.com/content/articles/1234
Accept: application/vnd.com.exmaple.article.orig+json
Option 1 and Option 3
Both are perfectly good solutions. I like the way Option 1 looks better, but that is just aesthetics. It doesn't really matter. If you choose one of these options, you should have requests to the old URL redirect to the new location using a 301.
Option 2
This could work as well, but only if the two responses have a different Content-Type. From the description, I couldn't really tell if this was the case. I would not define a custom Content-Type in this case just so you could use Content Negotiation. If the media type is not different, I would not use this option.
Perhaps option 2 - with the header being a Content-Type?
That seems to be the way resources are served in differing formats; e.g. XML, JSON, some custom format
If I have a webservice that returns an image, is there a standard way to also have it return some structured data (in the simplest case, an additional string or number)?
See this question for a PHP example of a webservice that returns an image.
(But my question now is not specific to PHP.)
Possible solutions (mostly not very satisfying):
Put the extra data in the metadata of the image.
Put the extra data in the HTTP headers.
Have the webservice return a nonce URL from which the image can be fetched for a limited amount of time.
Base64-encode the image and make it huge string field in a JSON or XML data structure. (Thanks to Carles and Tiago.)
How would you do it?
(I don't really want to just split the webservice into two separate calls because the webservice takes a ton of parameters and it seems wasteful to send them all twice.)
HTTP headers are a viable choice as they can be parsed easily server side and client side. Another thing you can do is setup a 302 that redirects it to a URL with the image and data in the URL (e.g ->
hit http://mysite.com/bestimageever.png
get 302 to http://mysite.com/realbestimage.png?supercoolinfo=42
That'd be transparent to the user and most API clients will work (since they handle redirects)
Return the image's binary data encoded in base64, and the additional field:
{ image: "mIIerhdkwje...", data: "data" }
Base64 encoding gives you an overhead of 33% (you need 4 bytes for each 3 original bytes). Depending on the size of your data it may be better to replace this with the url of the binary data and issue a second request...
Protocol buffers are another choice. Protocol buffers aren't self-describing like XML or JSON, but they are much more compact on the wire. The Google library (http://code.google.com/p/protobuf) provides C++, Java, and Python libraries, and contributors have provided libraries for a lot of other languages (http://code.google.com/p/protobuf/wiki/ThirdPartyAddOns), including Javascript and PHP, so client writers should have an easy time working with the format.
isn't it possible to include the binary data to form the image inside the return json/xml? By this way, you could add as many fields as necessary and you could process this information in the client.
I'm developing a RESTful API service which initially will only be accepting and responding in JSON format. I want to follow standards and in case of requester's Accept header was different than JSON I want to respond with 406 HTTP status code to inform the requester I cannot output data in other format.
According to W3 I "SHOULD include an entity containing a list of available entity characteristics and location(s) from which the user or user agent can choose the one most appropriate" in my response.
How do I do that, because the above explanation doesn't tell me much. What is the mentioned entity?
Any ideas/suggestions?
EDIT
Initially I thought that maybe could be a comma separated list in Content-Type header but after rethinking maybe I should do the same thing browsers do and use Accept header? This makes much more sense actually, but I cannot find any information to support this.
Three issues here:
First, the note from RFC 2616 is meant to address URI schemes where responses of different types are made available at various URI's, such as "/path/to/thing.xml" vs "/path/to/thing.json". That's not always a popular choice, but if you can do that, do so and include hyperlinks to each one in the "entity"; that is, in the body of the response. Since the RFC doesn't mandate a Content-Type or processing model for such links, you're on your own regarding how to return them, but HTML with <a> tags is common and useful.
If you don't want to expose multiple types at separate URI's, but just want to expose one type at the original URI, then it's perfectly fine to respond with 406 and an entity that simply says which types the resource can emit.
Second, note that most web browsers send */* in the Accept header (with a low quality value), which should match any Content-Type. In addition, the spec says "...if no Accept header field is present, then it is assumed that the client accepts all media types." So the cases where you should be raising 406 are rare.
Third, don't emit a Content-Type response header that is anything other than the Content-Type of the response entity. It should not be used to list acceptable types. You should also not emit a response header named 'Accept'; the 'Accept' header is for requests only; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
Simplified code example: http://pastebin.com/9ZQxSXi9
Hi
I wanted to experiment with the restlet 2.0 library and the gpodder webservice but somehow i reached a point where I can't see the wood for the trees.
The service in the example requires HTTP authentication and to post some JSON content to a URL.
Nothing that complicated but somehow even though the debug view claims the request object to contain the necessary content the RESTful webservice's response leads me to believe the HTTP header of the request was missing the content.
Any ideas on what's the reason? Thanks in advance.
The problem is that that none of the implementation of WriterRepresentation I've seen (JsonRepresentation, JacksonRepresentation, XStreamRepresentation) set the size of the representation when an object is passed. So if you create a new JacksonRepresentation(map) the size is not calculated.
You have to compute manually the length of the map content and calling Representation.setSize().
Or, as I did, use a
new JsonRepresentation(" a json string... ");
This constructor is able to compute the size, of course, that's the string length, so the proper content-length header is set and everything works smooth.
I have a resource at a URL that both humans and machines should be able to read:
http://example.com/foo-collection/foo001
What is the best way to distinguish between human browsers and machines, and return either HTML or a domain-specific XML response?
(1) The Accept type field in the request?
(2) An additional bit of URL? eg:
http://example.com/foo-collection/foo001 -> returns HTML
http://example.com/foo-collection/foo001?xml -> returns, er, XML
I do not wish to oblige machines reading the resource to parse HTML (or XHTML for that matter). Machines like the googlebot should receive the HTML response.
It is reasonable to assume I control the machine readers.
If this is under your control, rather than adding a query parameter why not add a file extension:
http://example.com/foo-collection/foo001.html - return HTML
http://example.com/foo-collection/foo001.xml - return XML
Apart from anything else, that means if someone fetches it with wget or saves it from their browser, it'll have an appropriate filename without any fuss.
My preference is to make it a first-class part of the URI. This is debatable, since there are -- in a sense -- multiple URI's for the same resource. And is "format" really part of the URI?
http://example.com/foo-collection/html/foo001
http://example.com/foo-collection/xml/foo001
These are very easy deal with in a web framework that has URI parsing to direct the request to the proper application.
If this is indeed the same resource with two different representations, the HTTP invites you to use the Accept-header as you suggest. This is probably a very reliable way to distinguish between the two different scenarios. You can be plenty sure that user agents (including search engine spiders) send the Accept-header properly.
About the machine agents you are going to give XML; are they under your control? In that case you can be doubly sure that Accept will work. If they do not set this header properly, you can give XML as default. User agents DO set the header properly.
I would try to use the Accept heder for this, because this is exactly what the Accept header is there for.
The problem with having two different URLs is that is is not automatically apparent that these two represent the same underlying resource. This can be bad if a user finds an URL in one program, which renders HTML, and pastes it in the other, which needs XML. At this point a smart user could probably change the URL appropriately, but this is just a source of error that you don't need.
I would say adding a Query String parameter is your best bet. The only way to automatically detect whether your client is a browser(human) or application would be to read the User-Agent string from the HTTP Request. But this is easily set by any application to mimic a browser, you're not guaranteed that this is going to work.