4 ms·
Let me say first of all that I'm glad they're working on standardizing this. When making REST APIs, I find HTML form scaffolds incredibly useful, but it means t
by rspeer 12y ago
Let me say first of all that I'm glad they're working on standardizing this. When making REST APIs, I find HTML form scaffolds incredibly useful, but it means that you probably have to accept both JSON (because JSON is reasonable) and occasional form-encoding (because forms), leading to subtle incompatibilities. Or you have to disregard HTML and turn your forms into JavaScript things that submit JSON. Either way, the current state is ugly.
Here's the part that I don't particularly like, speaking of subtle incompatibilities:
EXAMPLE 2: Multiple Values
<form enctype='application/json'>
<input type='number' name='bottle-on-wall' value='1'>
<input type='number' name='bottle-on-wall' value='2'>
<input type='number' name='bottle-on-wall' value='3'>
</form>
// produces
{
"bottle-on-wall": [1, 2, 3]
}
I've seen this ugly pattern before in things that map XML to JSON. Values spontaneously convert to lists when you have more than one of them. Here come some easily overlooked type errors.
I don't know of any common patterns for working with "a thing or a list of things" in JSON; that kind of type mixing is the thing you hope to get away from by defining a good API. But all code that handles HTML JSON is going to have to deal with these maybe-list-maybe-not values, in a repetitive and boilerplatey way.
I hope that a standard such as this will eventually be adopted by real-life frameworks such as Django REST Framework, but I also hope that they just reject the possibility of multiple fields with the same name.
- IgorPartola 12y agoPHP handles this by having lists like this by requiring you to use an I put name like "bottle-on-a-wall[]". The brackets indicate that it should be a list. I don't hate this convention...
- andyfleming 12y agoYeah. I feel like the bracket syntax is better. The other example above isn't explicit enough, IMO.
- hayksaakian 12y agothe only problem with the bracket syntax is when it comes to nested things <form enctype='application/json'> <input name='wow[such][deep][3][much][power][!]' value='Amaze'> </form> // produces { "wow": { "such": { "deep": [ null , null , null , { "much": { "power": { "!": "Amaze" } } } ] } } }
- joesb 12y agoWhat's the problem with that? If it's deeply nested, then it's deeply nested, no matter what.
- byuu 12y agoIt's pedantic, but it's a tad clunky now: I'd use something like "wow/such/deep[3]/much/power/!" to differentiate child nodes from array indexes, and also strongly advise against a node named "!" on principle. Of course then you'd say "but I want '/' in my node name!", and then you get to bikeshed an escape sequence, but you'd need that anyway for a node name with '[' or ']' in it. However, what they've done is workable if all the browser vendors implement it.
- stephenr 12y agosquare brackets are a reasonably common way to access data in an hash-like object. both Javascript (objects) and PHP (associative arrays) use/allow square brackets for this.
- ajanuary 12y agoI don't think multiple fields with the same name is designed to be a normal mode of operation. If you actually want an array, use the [] suffix. But if you have a bug which produces a form with multiple fields with the same name, what should it do? I can think of two strategies: last one wins and the proposal. Both are probably going to lead to things going wrong in the backend. At least with the proposal you: A) can detect it with boilerplate that looks for arrays where you expect primitives. B) figure out what the original data was if you need to try and manually repair it. I'm sure we'll see lots of bad tutorials suggesting you just use the same field name to make an array though :(
- stephenr 12y agodo any server-side environments currently present an array/array-like structure from request parameters with duplicate names (and specifically without any kind of array indicator, like name[] in php requests for example)?
- tomchristie 12y agoSure, yes. In Python land for example Django and Flask both present the request parameters in a dictionary-like data structure that supports lookup of the complete list of values passed for a given name. Regular lookups will give you just a single value, but they also present an interface to get the complete list.
- griffindy 12y agojersey[0], the reference implementation of JAX-RS[1] does this if you specify an incoming query string parameter as a `List` [0] https://jersey.java.net/ https://jersey.java.net/ [1] https://jax-rs-spec.java.net/ https://jax-rs-spec.java.net/
- tomchristie 12y agoThink that's fair point, yup. Very easy to do unintentionally, and it's non-intuitive that it'll suddenly change the return type. It's not clear if this style is really necessary. Why not just use the indexed syntax in this case? I guess it may be the authors intention to mirror form encoded submissions, that would send all of these values to the server. I'd suggest raising the point on the issue tracker so that it at least gets sufficient design discussion. https://github.com/darobin/formic/issues https://github.com/darobin/formic/issues
- richdougherty 12y agoWell, the safe way would be to mirror the current form spec and treat everything as arrays of strings by default. <form enctype='application/json'> <input type='text' name='fruit' value='apple'> <input type='number' name='bottle-on-wall' value='1'> <input type='number' name='bottle-on-wall' value='2'> <input type='number' name='bottle-on-wall' value='3'> </form> { "fruit": ["apple"], "bottle-on-wall": ["1", "2", "3"] } Then add attributes to explicitly give the structure. Since this is a browser spec we can add attributes. Here's the same form but with some attributes giving the explicit encoding. <form enctype='application/json'> <input type='text' name='fruit' value='apple' enc='string'> <input type='number' name='bottle-on-wall' value='1' enc='array/number'> <input type='number' name='bottle-on-wall' value='2' enc='array/number'> <input type='number' name='bottle-on-wall' value='3' enc='array/number'> </form> { "fruit": "apple", "bottle-on-wall": [1, 2, 3] } Dynamically varying JSON structures by form names and number of form elements is definitely going to be a source of bugs and security problems.