Open renatoathaydes opened 8 years ago
BTW this will affect your performance quite a lot as parsing mimetypes and matching them is expensive! You can avoid parsing the Accept header at all if the user does not specify the mimetype for a route, though!
Here are my current thoughts on this subject: https://gitter.im/bjansen/gyokuro?at=5675b586f31bbe91555b54dd
Basically, if gyokuro could automatically (de)serialize objects based on Content-type
and Accept
headers, would you still need this feature?
Since content types describe how data is sent, but don't affect the actual data, I can't really think of valid use-cases where we would want different handlers based on the content type. However, if you have such scenario in mind, I would be interested in hearing it.
This could be a nice optional feature (to serialise Objects automatically based on content-type). To think everyone would want it done this way would be very wrong.
Many API designers choose to not use the Accept
header and use other means (query parameter, resources that look like file names with extensions) and want to be able to map those to the actual data view.
See how the big REST frameworks do this (they all allow doing what you're suggesting, but also allow many other ways to do it).
Sure, it's still possible to map route("/resource.xml")
and route("/resource.json")
to different handlers, or to inspect the Request
manually to detect how the data should be transformed.
I was just wondering if adding a third parameter to get(route, handler, mimeType)
was still useful, given the other options we now have.
Anyway this should be fairly easy to implement, I just have to make sure this doesn't affect the routing performance if no MIME type is specified. I already adapted a MIME parser for #3, and guess what, it's also based on MIMEParser ;)
I was just wondering if adding a third parameter...
What??
I never requested a third parameter or whatever... I asked for support for Mime types only... how that support is added is up to the implementer.
What's this then?
Can you give me an example of what you'd like to do with MIME types? Do you just want to be able to call bestMatch(["application/xml", "application/json"], req.contentType)
?
Oh, come'on, you asked how Spark did that, and I showed it to you...
Sorry, but if you have a web framework and you don't support content negotiation via mime types, with all honesty, your framework is not worth a look. Just read about HTTP content negotiation, wikipedia has a good article on it:
You still haven't answered my question. I understand how content negotiation works, no need to point me to wikipedia. I just want to know what you are expecting in this issue, because honestly "Support MIME types" means nothing and everything.
If you want to be able to retrieve or set headers, it's already possible.
If you want to be able to call a handler or another based on what the client accepts, then say it clearly.
If you want advanced configuration like Spring MVC provides (i.e. being able to call a handler based on a "file extension", or a given parameter), then say it clearly.
I can't implement features if I don't know what people are expecting!
A simple Boolean matches(Request)
could handle a lot of cases:
Boolean mimeMatches({String+} mimeTypes)(Request req)
=> mimeParser.bestMatch(mimeTypes, req.contentType) exists;
get("/foo", (req, resp) => "is JSON", mimeMatches("application/json"));
get("/foo", (req, resp) => "is other", mimeMatches("*/*"));
Boolean extensionMatches(String ext)(Request req) => req.path.endsWith(ext);
Boolean paramMatches(String param, String value)(Request req)
=> req.parameter(param) == value;
get("/users/:id/profile", (req, resp) => "is JSON", paramMatches("format", "json"));
get("/users/:id/profile", (req, resp) => "is XLS", paramMatches("format", "xls"));
But you are asking me to design the feature for you, and I don't have time to do that. I can only say what a decent framework should support:
In case of request error:
If you are asking my personal opinion on how this should be supported, then I'm sorry but I don't know because I am not the designer of this framework and I have no time to do so.
Hope you can figure a good way out to solve this and the multitude of other things web frameworks need because I would like a useful framework in Ceylon, because using existing Java ones from Ceylon has been a pain so far.
Add support according to the specification: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
Check out the JAX-RS way of doing it: https://docs.jboss.org/resteasy/docs/1.0.2.GA/userguide/html/JAX-RS_Content_Negotiation.html
Guava has a MediaType class that helps a little bit with matching accept headers and routes: http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/net/MediaType.html
You can copy the MIMEParser from my project if you want (I also copied it, but gave credit to the author - Spark also copied but did not even acknowledge): https://github.com/renatoathaydes/easy-jetty/blob/master/easy-jetty-core/src/main/java/com/athaydes/easyjetty/external/MIMEParse.java