Accept/Content-Type header based processing in Quart and Quart-Schema - quart

Because I am rewriting a legacy app, I cannot change what the clients either send or accept. I have to accept and return JSON, HTML, and an in-house XML-like serialization.
They do, fortunately set headers that describe what they are sending and what they accept.
So right now, what I do is have a decoder module and an encoder module with methods that are basically if/elif/else chains. When a route is ready to process/return something, I call the decoder/encoder module with the python object and the header field, which returns the formatted object as a string and the route processes the result or returns Response().
I am wondering if there is a more Quart native way of doing this.
I'm also trying to figure out how to make this work with Quart-Schema. I see from the docs that one can do app.json_encoder = <class> and I suppose I could sub in a different processor there, but it seems application global, there's no way to set it based on what the client sends. Optimally, it would be great if I could just pass the results of a dynamically chosen parser to Quart-Schema and let it do it's thing on python objects.
Thoughts and suggestions welcome. Thanks!

You can write your own decorator like the quart-schema #validation_headers(). Inside the decorator, check the header for the Content-Type, parse it, and pass the parsed object to the func(...).

Related

Returning JSON format from ASP.NET web API

I know this question is been discussed many times but for me those solutions are not working. I want to return JSON data from my ASP.NET web API. I am hitting the end point using Firefox REST client plugin.
What I have tried:
I have specific accept header : Accept: application/json. Use accept header
Removed the XML formatter on Application_Start method
var formatters = GlobalConfiguration.Configuration.Formatters;
formatters.Remove(formatters.XmlFormatter);
This is how I return data at the end
return myModel.OrderBy(d => d.SortOrder);
Where myModel is just a class with few public property. I am not decorating this class or its property with any attribute.
But these two approach's are not working. I am still getting data in XML format :(
Please provide your suggestions.
I would like to introduce you to http://www.servicestack.net/
This is rest API framework that hooks up with .net.
It does everything what you require .
https://docs.google.com/presentation/d/16ey0MrpHOSz5N5sjctAliOgYWO3ZYeJe070fLZlPdrE/present#slide=id.i27
FROM COMMENT
Check that the application/json header is the first header and has a q=1 quality attribute: "application/json;q=1".
You can read more about quality attributes in the specs. Basically they are a way for a client of providing a preference system on the returned datatype.
To answer your other question (when I have explicitly removed the XML format in the code, why I was getting the data in XML format?), I can only guess what was going on: either the header was not setup correctly or the client was defaulting the other header to a different quality value.
Another guess could be that your way of removing the formatter is wrong: you can check this answer on SO or this article for alternative methods and see if they do the trick for you as well.

How do you change the default format to XML in Symfony?

I'm writing a restful XML API for a university assignment, the spec requires no HTML frontend.
There doesn't seem to be any documentation (or guessable functionality) regarding how to change the default format? Whilst thus far I have created all templates as ...Success.xml.php it would be easier to just use the regular ones and set this globally; I really expected this functionality to be configurable from YAML.. yet I have found some hard coded references to the HTML format.
The main issue I'm encountering is that part of the assessment is returning a 404 in a certain way (not as a 404 :/), but importantly it must always return XML, and the default setup of a missing route is a HTML 404 not XML (so it only works when I use forward404 from an action running via a XML route.
So in summary, is there a way to do this / what class(es) do I have to override?
Try putting this in factories.yml
all:
request:
class: sfWebRequest
param:
default_format: xml
That will still need the template names changing though. It will just mean that urls that don't specify a format will revert to xml instead of html.
You can subclass sfPHPView and override the initialise method to affect this (copy paste the initialise method from sfView) - the lines like this need changing:
if ('html' != $format)
You then need to change the view class used ... try this:
http://mirmodynamics.com/post/2009/02/23/symfony%3A-use-your-own-View-class

Multiple key/value pairs in HTTP POST where key is the same name

I'm working on an API that accepts data from remote clients, some of which where the key in an HTTP POST almost functions as an array. In english what this means is say I have a resource on my server called "class". A class in this sense, is the type a student sits in and a teacher educates in. When the user submits an HTTP POST to create a new class for their application, a lot of the key value pairs look like:
student_name: Bob Smith
student_name: Jane Smith
student_name: Chris Smith
What's the best way to handle this on both the client side (let's say the client is cURL or ActiveResource, whatever..) and what's a decent way of handling this on the server-side if my server is a Ruby on Rails app? Need a way to allow for multiple keys with the same name and without any namespace clashing or loss of data.
My requirement has to be that the POST data is urlencoded key/value pairs.
There are two ways to handle this, and it's going to depend on your client-side architecture how you go about doing it, as the HTTP standards do not make the situation cut and dry.
Traditionally, HTTP requests would simply use the same key for repeated values, and leave it up to the client architecture to realize what was going on. For instance, you could have a post request with the following values:
student_name=Bob+Smith&student_name=Jane+Smith&student_name=Chris+Smith
When the receiving architecture got that string, it would have to realize that there were multiple keys of student_name and act accordingly. It's usually implemented so that if you have a single key, a scalar value is created, and if you have multiples of the same key, the values are put into an array.
Modern client-side architectures such as PHP and Rails use a different syntax however. Any key you want to be read in as an array gets square brackets appended, like this:
student_name[]=Bob+Smith&student_name[]=Jane+Smith&student_name[]=Chris+Smith
The receiving architecture will create an array structure named "student_name" without the brackets. The square bracket syntax solves the problem of not being able to send an array with only a single value, which could not be handled with the "traditional" method.
Because you're using Rails, the square bracket syntax would be the way to go. If you think you might switch server-side architectures or want to distribute your code, you could look into more agnostic methods, such as JSON-encoding the string being sent, which adds overhead, but might be useful if it's a situation you expect to have to handle.
There's a great post on all this in the context of JQuery Ajax parameters here.
Send your data as XML or JSON and parse whatever you need out of it.

mvc.net DateTime with Time part in URI

I have a set of actions that are returning time-series data with-in ranges specifiable to the minute.
They work fine with querystrings,
i.e.
/mycontroller/myaction?from=20091201 10:31&to=20091202 10:34
with or without URL encoded colons, but I thought it would be nice to have a pretty URL
/mycontroller/myaction/from-20091201 10:31/to-20091202 10:34
but this now strikes fear in the hear of IIS as it doesn't like colons in the URI so I get 'Bad Request' responses.
My question then, is what's a recommended/standard course of action to ensure I can keep the time in there?
Do I need to write a custom ModelBinder to parse my own datetime format? Should the actions just take strings for from and to and parse with a custom format eg "YYYYMMDD-HHmm". Can I specify a custom format somewhere? If so where? Or should I just give this up as folly and stick with querystring parameters?
Oh, and I see a lot of people go on about RESTful URLs; from what I've read there's nothing that says query strings aren't RESTful - it's more about appropriate use of existing HTTP action types.
You're right REST doesn't mean if it's its not in a folder structure its not REST.
The path structure is there to describe the resource. Querystrings can still be used to describe a filtered subset of such a resource. A date range fully qualifies as a filter criteria and should thus be perfectly RESTful being passed in as a querystring.

How to pass parameters between rails applications?

I have to pass parameters between two rails apps. In one side (sender) I have an array of hashes. I have a code like the following to send the data:
http = Net::HTTP.new('localhost', '3030')
result = http.post('/processar_lotes', my_array_of_hashes)
Some questions
Is there any (kind of) serialize or something like this that I can pass to the other app?
At the other side, how can I de-serialize the information?
Is there a limit to the size of what I pass as a parameter?
To answer your questions:
There are many ways to 'serialize' the data. You can use your own custom format, or use a standard one. For example, you can try to use the Rails to_xml method, or the to_json method. You can also use Ruby's Marshal object.
Depending on your choice, this might be from_json, from_xml, Marshal.load, or your own custom reader.
Normally, this is unlimited for HTTP posts, but depending on your server configuration, it could be less.
Probably not the answer you're looking for, but I'd use XML. This would make your application much more flexible than using language-specific serialization.
It shouldn't be too hard to convert the array to XML and back.
EDIT: You might wanna check out ROXML and XML::Mapping.

Resources