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 validator idea.
I created a couple
feature branches which you can review/pull at the links
below. This involves changes to both core-contracts and
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
The order of
operations with regard to unmarshaling and validation looks
provided in the request)
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.
Assuming those 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
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.
Comments are 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() handlers.
| IoT DellTech
Round Rock, TX USA