Let me know your thoughts. We’ll probably
be talking about this at this week’s meeting.
Hi all -- I
wanted to follow up on this discussion we've been having
in the Core Working Group about validating our contract
models and where that responsibility lies. This past week
we talked about two options.
1.) Using a JSON
2.) Creating a
validator implementation that can be called as part of the
UnmarshalJSON operation found in some of our models.
I explored the
JSON Schema solution a bit on Thursday afternoon with help
from Intel, but I did not find it palatable. The schema
has to be created and maintained then loaded at runtime
from either URL, file or inline string. Child types have
their schema, but that schema must be either be repeated
in the schema of the parent type or referenced via a
pointer. This all seemed like too much work so before
getting seriously into it, I decided to work on the
I created a
couple feature branches which you can review/pull at the
links below. This involves changes to both core-contracts
ProvisionWatcher I have used DeviceService in my example
above because it already had an UnmarshalJSON() method in
place, and also with the ProvisionWatcher I'd have to
account for DeviceProfile as well. I just wanted to get
something up and going to try and prove the concept, so
the scope was more reduced by using DeviceService.
Here's a sample
request I'm using to test:
home variable speed
In the request
body above there are two issues. First, the operatingState
value is invalid. Second, the Addressable is missing. If
you execute the above locally, you'll receive a 400 (Bad
Request) with the error message "invalid OperatingState
If you fix the OperatingState value, then you'll still
receive a 400 with a new error message "Addressable ID and
Name are both blank". This is coming from the validator
inside of the Addressable model within core-contracts. I
noticed that we'll have the opportunity to slim our
controller logic by moving the server-side validation we
do today into the models. We'll also have consistent state
validation (example: validation today is different
depending on if you're adding a new Device Service versus
updating an existing one).
The order of
operations with regard to unmarshaling and validation
looks like this
(if provided in the request)
(if provided in the request)
Herein is the only
thing that gives me minor heartburn about the solution.
The validate() method of both OperatingState and
AdminState are called as part of their
respective UnmarshalJSON implementations. It doesn't
have to be but I thought it made sense to do so since it
allows us to fail faster if we detect a problem.
pass, then DeviceService calls its own validate() method
which takes care of validating all child types. This is
necessary in case a child type's key was omitted in the
JSON. This means validation for any of the child types
can occur twice -- a cheap operation to be sure, but
redundant at times.
As an aside, you
will see changes in the feature branches related to the
elimination of models.Service from core-contracts.
Nothing else was composed from this model other than the
DeviceService and I felt that eliminating it would
simplify the solution.
welcome. If this looks like a viable approach to folks,
then there might be some bandwidth soon to undertake
adding UnmarshalJSON to the models that do not have
them, and implementing the necessary validate()
| IoT DellTech
Round Rock, TX USA