[openstack-dev] [openstack-sdk-php] discussion: json schema to define apis

Jamie Hannaford jamie.hannaford at rackspace.com
Mon Apr 28 15:34:47 UTC 2014


Thanks Matt for bringing up these questions - I think having this kind of discussion is essential for such a big idea. It also helps me clarify my own thinking towards this issue.

Before I answer, I want to point out that I'm not staunchly for or against any particular idea. I do think that schemas offer a lot of advantages over writing user-land code, but I'm more than willing to abandon the proposal if we all determine there's a stronger and more compelling alternative.

1. Why use schemas instead of userland code?

I've put my answer to this question here: https://wiki.openstack.org/wiki/OpenStack-SDK-PHP/JSON-schema

2. How will debugging work?

I'll highlight two conceivable issues which might need debugging. The first issue is the API rejecting a request for whatever reason (i.e. a proxy modifying headers); the second issue is when a data structure returned from the API fails to validate against a particular schema file.

Issue 1: Malformed requests
There are two reasons why a request would fail: if an end-user stocks it with bad data, or if something in the middle deforms it. A very easy solution to the first problem is using schemas to perform basic parameter checking before a request is serialized. If we know, for example, that the API is expecting a particular value - or a particular header - the schema is in charge of making that happen. Performing basic validation catches most errors - and debugging is very easy due to the exception thrown. If you're ever in doubt, you just refer to the schema to see what was serialized into a request in the same way you do for a concrete class method.

If something in the middle deforms the request, the API will naturally reject it. When it comes to debugging this issue, all you need to do is wrap your original code in a try/catch block and use Guzzle's BadResponseException to return the API's response. You can easily see the type of failure through the HTTP status code, and the exact reason why the request failed. So it doesn't matter where the failure happens - all that matters is that there's a way to catch and spit out the API's response and the originating request.

Issue 2: Incorrect API data
Say we've defined that a Server has two properties: a name (which is a string) and metadata (which is an object). If the API returns a name as an array, that obviously fails validation. When the schema code goes to validate the API data, it will raise validation error when it comes to validate that "name" property. How you consequently use this validation error them is completely up to you: you could output it to STDOUT, you could save it to a local log on the filesystem, you could buffer it temporarily in memory.

Any API data that does not validate successfully against a schema should not be presented to the end-user. So if a "created_date" property is returned, that isn't defined in our schema, it should not be populated in the resulting model. The model returned to the end-user would be a simple object that implements \ArrayAccess, meaning that it can be accessed like a simple array.

3. Where would JSON schemas come from?

It depends on each OpenStack service. Glance and Marconi (soon) offer schemas directly through the API - so they are directly responsible for maintaining this - we'd just consume it. We could probably cache a local version to minimize requests.

For services that do not offer schemas yet, we'd have to use local schema files. There's a project called Tempest which does integration tests for OpenStack clusters, and it uses schema files. So there might be a possibility of using their files in the future. If this is not possible, we'd write them ourselves. It took me 1-2 days to write the entire Nova API. Once a schema file has been fully tested and signed off as 100% operational, it can be frozen as a set version.

4. What would the workflow look like?

I don't really understand what you mean: can you elaborate?

5. How does schema files handle business logic?

That's a really great question. I've written a brief write-up here: https://wiki.openstack.org/wiki/OpenStack-SDK-PHP/JSON-schema-business-logic<https://wiki.openstack.org/wiki/OpenStack-SDK-PHP/JSON-schema-business-logic#So_how_can_it_be_done_well.3F>


Jamie

From: Matthew Farina <matt at mattfarina.com<mailto:matt at mattfarina.com>>
Date: Thursday, April 24, 2014 at 5:42 PM
To: Jamie Hannaford <jamie.hannaford at rackspace.com<mailto:jamie.hannaford at rackspace.com>>, "OpenStack Development Mailing List (not for usage questions)" <openstack-dev at lists.openstack.org<mailto:openstack-dev at lists.openstack.org>>
Cc: "sam.choi at hp.com<mailto:sam.choi at hp.com>" <sam.choi at hp.com<mailto:sam.choi at hp.com>>
Subject: [openstack-sdk-php] discussion: json schema to define apis

Jamie (and whom ever else wants to jump in),

It's been proposed to use json schema to describe the API calls rather
than code. The operations to perform and what they do would be
described rather than coded and then some code would use the schema to
know how to act.

Others are already doing this. For example, the AWS SDK for PHP. Take
their S3 structure as an example
https://github.com/aws/aws-sdk-php/blob/master/src/Aws/S3/Resources/s3-2006-03-01.php.
The ability to do this goes beyond this one example. It just appears
to be something similar to what we're considering.

Given this in the scope of PHP I've got a number of questions. Several
of these I've compiled while discussing this with others so they don't
represent my point of view. Rather, they are just a list of
outstanding questions. Since this is a different method for handling
the API calls from the other SDKs being built the concept should be
really vetted.

Here are the questions:

1. Why use json schema rather than other reuse methods? I've discussed
the use of json schemas with others and those working on the other
languages have not been interested in json schema at the moment. Why
do it differently given the context?

Note, it might be worth looking at the python SDK which is doing
things differently. If I understand it right they are moving aware
from using managers and resources all together.

2. How will debugging work in practice? For example, a call is made
from behind a proxy. The proxy alters the HTTP headers so the request
fails and an exception is thrown. The schema and endpoint are valid.
It's something in the middle that changed things. Walking through the
code goes through magic methods to handle the schema. How would
debugging that work to understand what's happening compared to what
was expected.

3. Where would the json schemas for services come from and who would
manage them?

4. What would the workflow look like for working with the schemas at
both execution time for everyday use and for testing?

5. How would logic happen? Sometimes a request to an API is more than
just a request and response. For example, calling to something in
object storage where the object does not exist. The transport layer
will throw an exception (this goes all the way down to Guzzle throwing
one) that needs to be caught and managed. How should cases with some
logic like this be handled and easy to understand?

Thanks for looking into this. The topic has really sparked my
interest. I for one am really curious about the practicalities of
using json schema and the developer experience around it.

- Matt Farina




Jamie Hannaford
Software Developer III - CH     [experience Fanatical Support]

Tel:    +41434303908
Mob:    +41791009767
        [Rackspace]



Rackspace International GmbH a company registered in the Canton of Zurich, Switzerland (company identification number CH-020.4.047.077-1) whose registered office is at Pfingstweidstrasse 60, 8005 Zurich, Switzerland. Rackspace International GmbH privacy policy can be viewed at www.rackspace.co.uk/legal/swiss-privacy-policy
-
Rackspace Hosting Australia PTY LTD a company registered in the state of Victoria, Australia (company registered number ACN 153 275 524) whose registered office is at Suite 3, Level 7, 210 George Street, Sydney, NSW 2000, Australia. Rackspace Hosting Australia PTY LTD privacy policy can be viewed at www.rackspace.com.au/company/legal-privacy-statement.php
-
Rackspace US, Inc, 5000 Walzem Road, San Antonio, Texas 78218, United States of America
Rackspace US, Inc privacy policy can be viewed at www.rackspace.com/information/legal/privacystatement
-
Rackspace Limited is a company registered in England & Wales (company registered number 03897010) whose registered office is at 5 Millington Road, Hyde Park Hayes, Middlesex UB3 4AZ.
Rackspace Limited privacy policy can be viewed at www.rackspace.co.uk/legal/privacy-policy
-
Rackspace Benelux B.V. is a company registered in the Netherlands (company KvK nummer 34276327) whose registered office is at Teleportboulevard 110, 1043 EJ Amsterdam.
Rackspace Benelux B.V privacy policy can be viewed at www.rackspace.nl/juridisch/privacy-policy
-
Rackspace Asia Limited is a company registered in Hong Kong (Company no: 1211294) whose registered office is at 9/F, Cambridge House, Taikoo Place, 979 King's Road, Quarry Bay, Hong Kong.
Rackspace Asia Limited privacy policy can be viewed at www.rackspace.com.hk/company/legal-privacy-statement.php
-
This e-mail message (including any attachments or embedded documents) is intended for the exclusive and confidential use of the individual or entity to which this message is addressed, and unless otherwise expressly indicated, is confidential and privileged information of Rackspace. Any dissemination, distribution or copying of the enclosed material is prohibited. If you receive this transmission in error, please notify us immediately by e-mail at abuse at rackspace.com and delete the original message. Your cooperation is appreciated.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openstack.org/pipermail/openstack-dev/attachments/20140428/b6801685/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image1c586e.JPG
Type: image/jpeg
Size: 3124 bytes
Desc: image1c586e.JPG
URL: <http://lists.openstack.org/pipermail/openstack-dev/attachments/20140428/b6801685/attachment.jpe>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image17b982.JPG
Type: image/jpeg
Size: 990 bytes
Desc: image17b982.JPG
URL: <http://lists.openstack.org/pipermail/openstack-dev/attachments/20140428/b6801685/attachment-0001.jpe>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: imagec7f21a.JPG
Type: image/jpeg
Size: 6844 bytes
Desc: imagec7f21a.JPG
URL: <http://lists.openstack.org/pipermail/openstack-dev/attachments/20140428/b6801685/attachment-0002.jpe>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image9a4264.JPG
Type: image/jpeg
Size: 1074 bytes
Desc: image9a4264.JPG
URL: <http://lists.openstack.org/pipermail/openstack-dev/attachments/20140428/b6801685/attachment-0003.jpe>


More information about the OpenStack-dev mailing list