[openstack-dev] [Keystone] Use JSON Schemas to validate API requests data

Doug Hellmann doug.hellmann at dreamhost.com
Wed Jun 5 17:43:35 UTC 2013


On Wed, Jun 5, 2013 at 12:46 AM, Ken'ichi Ohmichi <oomichi at mxs.nes.nec.co.jp
> wrote:

>
> Hi,
>
> On Tue, 04 Jun 2013 10:39:51 -0400
> Russell Bryant <rbryant at redhat.com> wrote:
> > >
> > >     WSME does type checking and validation.  Doug, can you comment
> further?
> > >
> > >
> > > WSME does type conversion/checking. I typically implement validation in
> > > the model class constructor so it's right there inline and easy to
> find.
> >
> > Ah, ok, I see where the line is now.  Thanks for the clarification.
> >
> > If there's value in doing jsonschema validation on top of WSME, it would
> > be interesting to see a prototype to see what it would look like.
>
> To compare both validation mechanisms, I'd like to pick two APIs.
> The one is Ceilometer "v2/alarms/" API for simple validation, and
> the other is Nova "v2/os-fixed-ips/{fixed_ip}/action" API for strict
> validation.
> I try to create these API schema prototypes like the following:
>
> == Ceilometer "v2/alarms/" API ======================================
>   *** Schema implemented with WSME ***
>   class Alarm(_Base):
>       alarm_id = wtypes.text
>       name = wtypes.text
>       description = wtypes.text
>       counter_name = wtypes.text
>       project_id = wtypes.text
>       user_id = wtypes.text
>       comparison_operator = wtypes.Enum(str, 'lt', 'le', 'eq', 'ne', 'ge',
> 'gt')
>       [snip]
>
>   *** Schema implemented with JSONSCHEMA ***
>   alarm = {
>       'type': 'object',
>       'properties': {
>           'alarm_id': {'type': 'string'},
>           'name': {'type': 'string'},
>           'description': {'type': 'string'},
>           'counter_name': {'type': 'string'},
>           'project_id': {'type': 'string'},
>           'user_id': {'type': 'string'},
>           'comparison_operator': {
>               'enum': ['lt', 'le', 'eq', 'ne', 'ge', 'gt']
>           },
>           [snip]
>       }
>   }
>
> == Nova "v2/os-fixed-ips/{fixed_ip}/action" ============================
>   *** Schema implemented with WSME ***
>   class FixedIpAction:
>       _reserve = None
>       _unreserve = None
>
>       def get_reserve(self):
>           return self._reserve
>
>       def set_reserve(self, value):
>           assert is_valid_ipv4(value), "invalid ipv4 data"
>           assert _unreserve==None "Both reserve and unreserve should not
> be specified"
>           self._reserve = value
>
>       def get_unreserve(self):
>           return self._unreserve
>
>       def set_unreserve(self, value):
>           assert is_valid_ipv4(value), "invalid ipv4 data"
>           assert _reserve==None "Both reserve and unreserve should not be
> specified"
>           self._unreserve = value
>
>       reserve = wsme.wsproperty(str, get_reserve, set_reserve)
>       unreserve = wsme.wsproperty(str, get_unreserve, set_unreserve)
>

This API looks odd to me. The "action" to take as part of the payload of
the message, where I would have thought they should be separate endpoints.
If there were separate reserve and unreserve endpoints in the API, then
each would only need to declare that they took an IPv4 address as an
argument, along with whatever else is needed (the instance id?). That IPv4
address would be represented by new WSME user-defined type, which would be
reusable throughout the APIs that work with network addresses. It would not
be possible to specify both reserve and unreserve at the same time, so you
wouldn't need that check at all.

Doug



>
>
>   *** Schema implemented with JSONSCHEMA ***
>   action = {
>       'type': 'object',
>       'oneOf': [
>           {
>               'properties': {
>                   'reserve': {'type': ('null', 'string'), 'format':
> 'ipv4'},
>               },
>               'required': ['reserve'],
>           },
>           {
>               'properties': {
>                   'unreserve': {'type': ('null', 'string'), 'format':
> 'ipv4'},
>               },
>               'required': ['unreserve'],
>           },
>       ]
>   }
>
> I think WSME is easy to implement API schema for simple validation,
> which checks parameter types only. The schema code is so simple.
>
> On the other hand, jsonschema is easy to do it for strict validation,
> which checks parameter types, lengths, ranges and formats.
> If implementing strict validation with WSME, we need to create getter/
> setter methods for each parameter and validation code is necessary in
> getter method.
>
>
> Thanks
> Ken'ichi Ohmichi
>
> _______________________________________________
> OpenStack-dev mailing list
> OpenStack-dev at lists.openstack.org
> http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openstack.org/pipermail/openstack-dev/attachments/20130605/2bb466b6/attachment.html>


More information about the OpenStack-dev mailing list