flask-rebar icon indicating copy to clipboard operation
flask-rebar copied to clipboard

Let's talk about content-negotiation

Open RookieRick opened this issue 5 years ago • 6 comments

Following up on recent PRs, figured I would open an Issue for now where we can kick some ideas around on the topic of content negotiation.

A few quick thoughts to kick things off. I would characterize our options as:

  1. Do nothing (ok now that's out of the way)
  2. Build our own content negotiation
  3. Add a dependency on some existing content negotiation library (I haven't looked deeply into these yet but found a couple like Flask-Accept, Flask-Negotiate, Flask-Negotiation)
  4. Punt content-type negotiation and add some recipes/examples that demonstrate how one could integrate Flask-Rebar with things like those in item 3.

Pros/cons I see of these:

  1. Duh, no good.
  2. Pro: We can make it work exactly how we want. Con: Risk of reinventing the wheel
  3. Pro: Citizenship badge for OSS :). Con: I like the fact that we are only dependent on the two core technologies that we are combining in Flask and Marshmallow and am hesitant to add to the Python equivalent of DLL-Hell.
  4. Pro: Still good OSS citizens (and without choosing sides - allow people to stick with what they like if they already have a preference). Con: Pushes some of the DLL-hell burden to our users

If I was forced to rank these I'd probably say 2 & 4 are a virtual tie for me, followed by 3, and then 1. Definitely interested to hear thoughts from our other contributors and users.

RookieRick avatar May 08 '19 03:05 RookieRick

@RookieRick I think there may be two separate discussions.

  1. Should endpoints registered with rebar be allowed to return anything other than a json encoded body in the response?
  2. If rebar endpoints can return multiple types of media in the response body, then how do we handle content headers (content-negotiation)?

We might want to agree on the first point before discussing the second?

airstandley avatar May 08 '19 17:05 airstandley

  1. Should endpoints registered with rebar be allowed to return anything other than a json encoded body in the response?

My $0.02 on this is that we should not impose json-only unless we absolutely must, in the interest of keeping rebar a generic broadly-usable extension of Flask. If we restrict to json with no way to override that, we risk blocking otherwise-valid uses of Flask. I'd advocate for treating json as our default (and possibly only "native" supported i.e. my option 4) while still ideally allowing flexibility for somebody that wants to return HTML or CSV or whatever suits their use case.

RookieRick avatar May 08 '19 17:05 RookieRick

  1. Should endpoints registered with rebar be allowed to return anything other than a json encoded body in the response?

We already do allow endpoints to return non JSON responses by setting the marshal schema to None (as documented here). Echoing @RookieRick , I think its important to allow for non JSON responses. I'm fairly certain we already have people doing this in production applications.

barakalon avatar May 08 '19 18:05 barakalon

My gut says we go with (2). OpenAPI 3.0 has much better support for content negotiation, and having full control over it will likely make generating the OpenAPI doc easier.

barakalon avatar May 08 '19 18:05 barakalon

I'm a bit ignorant on the intricacies of this still, but my naive concern is that supporting non-json encoded responses by not specifying a marshalling schema is not really supporting non-json responses, since the marshal_schema value basically defines the returns for the swagger definition.

If we are planning on supporting non-json marshalling and removing the assumptions that any marshalling means a json encoded response, then I agree it makes sense to have proper content negotiation.

I think (4) is ideal, but likely to overly constrain our ability to generate good OpenAPI 3.0 definitions. I'm pro (3) because from what I've seen of existing content-negotiation work, it's a bit of a nightmare of a problem, but I suspect that @barakalon's gut is right and we'll probably have to do (2) to get good OpenAPI docs generated.

airstandley avatar May 09 '19 02:05 airstandley

Adding the question label since we still haven't settled on an approach.

airstandley avatar Sep 17 '19 20:09 airstandley