Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MIME, someday, maybe* #78

Open
glyph opened this issue Aug 5, 2015 · 2 comments
Open

MIME, someday, maybe* #78

glyph opened this issue Aug 5, 2015 · 2 comments
Labels

Comments

@glyph
Copy link
Member

glyph commented Aug 5, 2015

In a properly REST application, the server should engage in content negotiation to deliver the client's preferred representation of a resource.

I would love to make it possible, within klein, to separate the reification of the resource (i.e. instantiation of a model object) from the serialization of that resource (i.e. invocation of a view).

For example: let's say we have an API, /foo, which is a JSON API that returns {"foo": "bar"}. However, the user might hit it in a web browser, where it might be more helpful to present this information via an HTML template (rendered, perhaps, via twisted.web.template).

I'd love to do something like this:

@something("/foo")
def foo(request, values):
    return {"foo": "bar"}

@foo.serializer("text/html")
def as_html(request, model):
    return someTemplate.fillSlots(**model)

@foo.serializer("application/json")
def as_json(request, model):
   return json.dumps(model)

Of course, serializing as JSON and HTML are probably two pretty common ones, so maybe there should be a less verbose way to set this up, simply a way to specify a template. I am not sure how this should look, I'd just like it to be easy. Also, this should be possible on inputs as well: you might want to accept parameters as either JSON or urlencoded key/value pairs.

*: With apologies to Marc Andreessen.

@wsanchez
Copy link
Member

I potentially disagree with the example provided:

A JSON document that describes some data and an HTML document that displays that data (in one of many possible ways) are not the same "concept" and should not be vended by the same resource, so the thing Glyph wants to do here is not, in fact, something a proper REST application should do.

That said, a JSON document that describes some data and a Protobuf or XML or whatever document that represents the same data may be an appropriate use of content negotiation, as would a photo that can be rendered as a JPG or PNG or whatever.

I mention that because if we end up with an example like this as a recommended way to write an app, I think that's unfortunate.

@glyph
Copy link
Member Author

glyph commented Jan 27, 2017

OK, I regret beginning with "properly REST" :). I don't put much stock in REST as a formal application architecture, and I don't really care if we are adhering to its religious tenets or not. It's very hard to tell if this specific idea (HTML including presentation information & JSON including only structure from the same resource) is "really" REST or not. There are some indications that it is, but there's more consensus that content negotiation generally is part of REST for deciding on different formats rather than different structures.

So, putting aside the idea of whether they're "really" the same concept or not: what's the benefit? As this blogger puts it, "less duplication of code".

If you're writing a web application that retrieves data from a backend, performs some logic, and returns it to a front-end, I believe it should be a strongly encouraged default that you should have structured data be available on day 1, even if what you're really targeting for reasons of optimization, SEO, or user experience is a prerendered HTML page. The goal here is not to commit to the same URL structure but rather to the same code. The negotiation is already rather ad-hoc (a query parameter, see #132), and there are good tooling reasons to avoid a pure Accept:-header based negotiation strategy. A URL segment might also be a perfectly reasonable way to accomplish the negotiation process, for example, exposing a /api/ prefix which is always JSON and an /app/ prefix which is always HTML.

So, all that said: what exactly do you think is the problem with offering these two resources from the same URL? What difficulties might it present? Would it be better to come up with some other default?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants