Closed bajtos closed 8 years ago
Both ?arg=FALSE
and ?arg=FalsE
should be coerced to `false.
This all looks really good and I'm glad you guys are taking a serious look at it.
urlencoding
is probably the trickiest part because there is so much sloppiness in this string-only input method. By far the most coercion should go there.
On the contentious issues:
[]
(no items) and null
(no items). But []
is much more convenient as you can simply iterate.urlencoded
boolean coercion, I think it should coerce 0
and 1
to boolean as this is often typical in querystrings due to perceived/legacy url size limits.Date
, otherwise it's potentially too much magic - the user must then know which date formats are coerced and which are not. Of course, I wouldn't recommend ever using the any
type or an untyped array.
?arg=
should be ''
for string
types only, null
otherwise.?arg=null
should be the string null
for string
types only, null
otherwise.any
should do less coercion than explicit typing (such as null
above) and should not coerce dates (too much magic).I think Date coercion should only happen when the input type is Date, otherwise it's potentially too much magic
Sure, and I thought we all agreed that we were moving away from implicit coercion.
I apologize for being somewhat out of the loop, but if I type a parameter as an actual model type (or is there any anonymous schema type?), will it coerce its attributes? E.g. something like `type: 'object', schema: {date: Date}' or the like.
If you specify type: 'SomeModel'
strong-remoting will use the converter specified by loopback to new SomeModel(arg)
, which will set default properties and apply all setters and getters. It will coerce based on the properties type
.
var properties = {date: {type: Date}};
var MyModel = loopback.createModel('MyModel', properties);
var data = {date: '2016-06-10T16:25:55.132Z'};
var inst = new MyModel(data);
assert(inst.date instanceof Date);
Done and released.
Based on the integration test suite written in #304, I am proposing to make the following changes/fixes in the way how we coerce input arguments.
I think most (if not all) of this changes can be considered as backwards-compatible fixes to be landed on 2.x too.
@STRML @ritch thoughts?
Terminology:
json body
- the argument is set to the full request body which is JSON encodedjson form
- the argument is read from a property in the JSON-encoded request bodyurlencoded
- the argument is read either from query string or from urlencoded request bodyTighten validation of required arguments
json body - any - required
should rejectnull
valuejson form - array - required
should reject empty request andnull
valuejson form - * - required
should reject empty request,null
value and empty string valueurlencoded - *
should reject empty query,?arg
,?arg=
,?arg=null
Reject scalar values for array type
json body - array of *
json form - array - required
Do not coerce missing value to empty array
This may be possibly controversial. Should we introduce a config option to control this behaviour?
json form - array of *
should convert empty body toundefined
json form - array of *
should convertnull
tonull
urlencoded - array of *
should convert?
,?arg
,?arg=
toundefined
Do not coerce values from JSON-encoded sources
json body - array of *
json form - array of *
json body - array of any
json form - array of any
json form - boolean
(reject strings, numbers, etc.)json form - date
(reject booleans, large numbers, non-date strings, etc.)json form - number
(reject strings, booleans, arrays, etc.)json form - object
(reject strings, booleans, numbers)json form - string
(reject booleans, numbers, objects, arrays, etc.)Allow
null
as a value for object typeConvert
null
input tonull
value:json body - object - optional
json form - *
urlencoded - *
Treat missing argument as
undefined
Set argument to
undefined
when not set:json form - *
urlencoded - *
- treat?arg
asundefined
Don't coerce too large numbers
urlencoded - any
- keep?arg=2343546576878989879789
as string valueRecognize scientific notation when parsing strings
urlencoded - any
- convert?arg=1.234e%2B30
to a numberMalformed JSON in urlencoded value should trigger 400 Bad Request
urlencoded - array of *
should reject?arg={malformed}
and?arg=[malformed]
urlencoded - object
should reject?arg={malformed}
and?arg=[malformed]
Convert numeric timestamps from urlencoded sources to number
?arg=0
should be converted tonew Date(0)
for bothurlencoded - date
urlencoded - array of date
Do not coerce array items from urlencoded sources
urlencoded - array of *
Do not coerce non-boolean values
urlencoded - boolean
should reject all values excepttrue
/false
, e.g.?arg=0
and?arg=1
Avoid
NaN
dates, return 400 Bad Request insteadExamples:
?arg=undefined
,?arg=true
, but also?arg=2343546576878989879789
Open points to discuss
Should we coerce date strings stored in object properties/array items from JSON sources for
type:object
,type:any
andtype:array
?Example inputs:
undefined
(argument is missing) andnull
(argument is provided withnull
value)??arg=
in query string/urlencoded request body? Should we treat it as an empty string or as a missing value??arg=null
, should we parse it asnull
or as a string"null"
?urlencoded - any
- should we coerce Date strings to Date instances? What formats other than the full ISO string should be recognized, e.g2016-05-01
orT09:30:00
?