MessageBodyWriter most suitable Variant - rest

The MessageBodyWriter.writeTo method includes MediaType mediaType and MultivaluedMap<String,Object> httpHeaders.
mediaType is supposed to be the most appropiate output format, but how is it being selected when multiple Accept header values are included (i.e. application/xml, q=0.5; application/json, q=0.9).
Besides, how is the best variant selected (language, etc.)? Using Request.selectVariant() is possible to do it automatically, but I haven't found how to do so within the MessageBodyWriter.
Thanks

Besides, how is the best variant selected (language, etc.)?
That really depends on the implementation.
but I haven't found how to do so within the MessageBodyWriter
Because MessageBodyWriter.writeTo doesn't really care about selecting the best variant. After checking a few implementations, like StringProvider, SerializableProvider or FormMultivaluedMapProvider it seems clear that they just take the input, and write it to the output stream in their respecitve formats: as a string, as a serialized object or as a form encoded string. They only use mediaType for such minor details as the character encoding they should use.
Therefore the decision about the most appropriate output format has to be decided before choosing the used MessageBodyWriter implementation as e.g. a StringProvider will always only output the string, and won't care if it's a JSON string or and XML string or something else.

Related

Identifying and formatting XML String to readable format in XMLParser

I am working in Swift and I have a set of Data that I can encode as a String like this:
<CONTAINER><Creator type="NSNull"/><Category type="NSNull"/><UMID type="NSArray"><CHILD>d1980b265cbd415c90f5d5f04efcb5df</CHILD><CHILD>7e0252c137c249fc92bd0f844effe27f</CHILD></UMID><Channels type="NSNumber">1</Channels></CONTAINER>
I am looking for a way to format this string as XML with indents so I can use XMLParser to properly read through it, which it currently does not. I imagine NSNull is when the object is empty, I just haven't seen this format so I don't know what to search for. Could it be closer to a Dictionary object? If so I'd be happy to format it as that as well.
I've also tried to create a XMLDocument from the data, but it doesn't fix the format.
EDIT:
I wanted to add a bit more information to help clarify what I am trying to do. This string above is derived from an encrypted piece of metadata from a file. In my code I identify the chunk of data that is encrypted, then decrypt it, and then convert that data to a string. It's worth noting that the string ends up having null characters in between each valid character, but I strip those out and end up with this string.
Copying this string into an XML Validator confirms it is valid XML. What is confusing to me is it's format, in which it has Object types such as NSNull and NSNumber. My post was originally hoping to identify this type of format. It seems like more than just XML.
In response to some of the comments, I have used XML Parser delegate with other XML strings and have a basic understanding of how it works. I should have originally mentioned that and instead said that XML Parser does not recognize any of these elements or strings within them.
UPDATE:
The issue ended up being the null characters in between each valid character. Stripping those out and then running it through XML Parser worked great. Thanks all.

Serving different media types in AWS Lambda with Java/Scala

When writing a function for AWS Lambda (in Java/Scala), the handler function can have one of different signatures:
// Raw input / output
def handleRequest(is: InputStream): OutputStream = ???
// Using the AWS dependency
def handleRequest(input: APIGatewayProxyRequestEvent, context: Context): APIGatewayProxyResponseEvent = ???
This is the two possible signatures I know of, at least. Maybe there is more.
The difference is that the first one is a raw response, that needs to be packed into a REST response by the API Gateway with manually configured properties like media type and response code.
The second response seems to utilize the Lambda Proxy Integration and will extract all configuration from the APIGatewayProxyResponse.
Now for my question:
The field body of APIGatewayProxyResponse is of type String.
To me it looks like this POJO is serialized to JSON before being sent to the API Gateway.
This would make it impossible to serve binary data like images or PDF files.
The raw OutputStream cannot carry the information about headers etc. (or can it?), which means I cannot serve multiple different media types.
Of course I could convert images, for example, to Base64. But that is far from optimal.
Is there a way I can serve different (binary and non-binary) media types (with correct headers etc.) in a single AWS Lambda handler? How do I have to configure the API Gateway for that?
Note: This answer is based on reading the docs. I haven't tried it in practice so it may not work.
If you open the "Output Format of a Lambda Function for Proxy Integration" section of the documentation you may see isBase64Encoded field and following text:
The output body is marshalled to the frontend as the method response payload. If body is a binary blob, you can encode it as a Base64-encoded string and set isBase64Encoded to true. Otherwise, you can set it to false or leave it unspecified.
And if you open APIGatewayProxyResponse in the .Net library you can see the IsBase64Encoded property there. It looks like it is just Java API that does not expose this field. But all the rest of the infrastructure should support it. You may also see that a similar field was added to APIGatewayProxyRequestEvent.java at some point but not to APIGatewayProxyResponse. So I think a following workaround should work: create your own APIGatewayProxyResponseEvent class with isBase64Encoded field and use it. Or just extend from the standard com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent and add this field in your subclass. I expect that if you match the naming convention, it should work. It should be marshalled to a JSON after all.

Converting a String to a Splittable in GWT

I'm maintaining a site written in GWT (2.5.0) that is used internally by our development team, and I've been experimenting with using AutoBeans for client side json parsing. I have a few objects with json that is not well defined — a developer can dump whatever json string he wants in there — so I'm using a Splittable property. In order to support editing this arbitrary json I'd like to convert a String into a Splittable, but I haven't found a straight-forward way of accomplishing this. Do I need to implement this interface myself or resort to something hacky like wrapping the json in another json object I can then decode into a throw-away AutoBean just to get a Splittable of the original json?
StringQuoter is the utility class which we do much of our manual Splittable work with.
Just user StringQuoter.create("some string"); to produce a Splittable whose payload is
"some string"
Once you have that splittable, you can assign it to a key in another splittable with the following method:
Splittable.assign(Splittable parent, String propertyName);
However, if you are trying to convert some arbitrary string which contains a JSON structure into a splittable, use StringQuoter.split(..) to create it. The resulting splittable can be queried as normal (i.e. what keys exist/don't exist, etc).

What is to prefer in Restlet: handleGet, handlePost OR represent, acceptRepresetation?

IMHO, there are two techiques to handle a query for a resource:
For http GET you can override represent(Variant variant) or handleGet().
For http POST the same applies with acceptRepresentation(Representation entity) and handlePost().
The doc for handleGet says:
Handles a GET call by automatically returning the best representation available. The content negotiation is automatically supported based on the client's preferences available in the request. This feature can be turned off using the "negotiateContent" property.
and for represent:
Returns a full representation for a given variant previously returned via the getVariants() method. The default implementation directly returns the variant in case the variants are already full representations. In all other cases, you will need to override this method in order to provide your own implementation.
What are the main differences between these two types of implementations? In which case should I prefer one over the other? Is it right that I can achieve with e.g. handleGet() everything that would work with represent()?
I first started using handleGet setting the entity for the response. When I implemented another project I used represent. Looking back i can't really say one way is better or clearer than the other. What are your expirences for that?
I recommend using represent(Variant) because then you’ll be leveraging the content negotiation functionality provided by the default implementation of handleGet(Request, Response).
BTW, lately I've started using the annotation-based syntax instead of overriding superclass methods, and I like it. I find it clearer, simpler, and more flexible.
For example:
#Post('html')
Representation doSearch(Form form) throws ResourceException {
// get a field from the form
String query = form.getFirstValue("query");
// validate the form - primitive example of course
if (query == null || query.trim().length() == 0)
throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, "Query is required.");
// do something
SearchResults searchResults = SearchEngine.doSearch(query);
// return a HTML representation
return new StringRepresentation(searchResults.asHtmlString(), MediaType.TEXT_HTML);
}
The advantages of using this approach include the incoming representation being automatically converted to a useful form, the method can be named whatever makes sense for your application, and just by scanning the class you can see which class methods handle which HTTP methods, for what kind of representations.

What is the HTTP content type for binary plist?

I am modifying a rails server to handle binary plist from an iPhone client via POST and PUT requests. The content type for text plist is text/plist, as far as I can tell. I would like the server to handle both text and binary plists, so I would like to distinguish between the two forms. What is the content type for binary plist?
I believe that most binary formats are preceded by application so maybe application/plist.
See the bottom of RFC1341.
Update
Like Pumbaa80 mentioned, since application/plist is not a standard mime-type it should be application/x-plist.
In RFC2045 it explains this:
In the future, more top-level types
may be defined only by a standards-track extension to this standard.
If another top-level type is to be used for any reason, it must be
given a name starting with "X-" to indicate its non-standard status
and to avoid a potential conflict with a future official name.