1

I'm starting a new project that consists in an Extjs 6 application with a pyramid/python backend.

Due to this architecture, the backend will only provide an RPC and won't serve any page directly. My implementation of such a thing is usually based on REST and will fit nicely this CRUD application.

Regarding data validation i would like to move from Colander/Peppercorn that i always found awkward to the simpler and more streamlined jsonschema.

The idea here would be to move all the parameters - minus the id contained in the url when is the case - of the various requests into a json body that could be easily handled by jsonschema.

The main problem here is that GET requests shouldn't have a body and i definitely want to put parameters in there (filters, pagination, etc).

There's probably some approach to REST or REST-like and JSONschema but i'm not able to find anything on the web.

Edit: someone mentioned the question about body in GET HTTP request. While putting a body in a GET HTTP request is somehow possible, it's in violation of part of HTTP 1.1 specification and therefore this is NOT the solution to this problem.

  • Possible duplicate of [HTTP GET with request body](http://stackoverflow.com/questions/978061/http-get-with-request-body) – CollinD Oct 07 '15 at 14:59
  • No it isn't. You CAN get a body in a HTTP GET request. It will work in some cases, but it's not what i want to do because it seems a bad hack. – Riccardo Cagnasso Oct 07 '15 at 15:04

3 Answers3

1

If I understand you correctly, you want to use JSON Schema for input validation, but you are struggling to figure out how to validate query parameters with JSON Schema in a RESTful way.

Unfortunately, there isn't a definitive answer. JSON Schema just wasn't designed for that. Here are the options I have considered in my own work with REST and JSON Schema.

  1. Convert query parameters to JSON then validate against the schema
  2. Stuff your JSON into a query param and validate the value of that param. (i.e. /foo/1?params={"page": 2, "perPage": 10})
  3. Use POST instead of GET and stick your fingers in your ears when people tell you you are doing REST wrong. What do they know anyway.

I prefer option 1 because it is idiomatic HTTP.

Option 2 is probably the easiest to work with on the back-end, but it's dirty.

Option 3 is mostly a joke, but in all seriousness, there is nothing in REST or HTTP that says a POST can only be used for creation. In fact, it is the most flexible and versatile of the HTTP methods. Think of it like a factory that does something. That something could generate and store a new resource or just return it. If you are finding that you need to send a large number of query parameters, it's probably not really a simple GET. My rule of thumb is that if the result is inherently not cacheable, it's possible that a POST is more appropriate (or at least not inappropriate).

Jason Desrosiers
  • 22,479
  • 5
  • 47
  • 53
  • Yes, i agree with your analysis. Still we are far from a proper solution. We would like to have a full jsonic api in a RESTful form, but the two thing doesn't concile, at least not perfectly. – Riccardo Cagnasso Oct 08 '15 at 11:27
0

I don't see why you need to do anything specific. In Pylons request.GET returns a dictionary (actually a MultiDict, but basically the same thing) of the parameters in the querystring. You can easily convert this to JSON or pass it directly to the schema validation.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • A NestedMultiDict is not "basically the same thing" as a dict. It can have multiple values for the same key and you can easily see how this cannot be: A) directly converted into a dict B) directly validated as a JSON file – Riccardo Cagnasso Oct 07 '15 at 15:59
  • 1
    Sorry, I don't see that at all. A MultiDict has a method [`dict_of_lists`](http://docs.pylonsproject.org/projects/pyramid/en/latest/api/interfaces.html#pyramid.interfaces.IMultiDict.dict_of_lists) which returns a dict where each key is a list; that's perfectly valid JSON. – Daniel Roseman Oct 07 '15 at 18:33
0

The cleanest would be to put the JSON string in a single query parameter. If you have a JSON Schema to validate it, the client could use the same JSON Schema, and would therefor already have the data in JSON form.

http://example.net/some/model/1?query={"foo":1,"bar":["baz","qux"]}

If you for some reason dislike having JSON in the query, you could use a standard for converting query parameters. There is no universally agreed-upon specification for param strings, but there are a few practices, depending on language and framework/library.

Example: http://example.net/some/model/1?foo=1,bar[]=baz,bar[]=qux

That might look cleaner to a new user, but will be more difficult if the client uses a lib/language that would querify JSON differently.

fiddur
  • 1,768
  • 15
  • 11