Thursday, October 28, 2010

HATEOS and resource navigation in vCloud API

HATEOS stands for Hypermedia as the Engine of Application State. This is a principle or constraint used by the designers when defining resources in RESTful way. Bottom line of this principle is that client needs to know the a fixed or top level URL and be able to access all the necessary resources. Which means every response or resource description should further indicate how to access either related resource or perform certain actions on the resource. Since resources are identified by URL and actions are also represented in the form of URL as we saw in earlier post, the resource description or the HTTP responses should include links or URLs for the navigation purpose.

This is the third level of maturity as described by Richardson. Lets see how vCloud API adheres to this principle.
vCloud API defines a top level URL http://my.vcloud.com/api/versions This URL provides information about all the versions supported by the vCloud Server. For every version supported there is log in URL associated with every version number (if there are more than one :-), which is obviously not the case for the version 1.0)
This is how it looks:
GET http://my.vcloud.com/api/versions
<SupportedVersions xmlns="http://www.vmware.com/vcloud/versions" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.vmware.com/vcloud/versions http://my.vcloud.com/api/versions/schema/versions.xsd">
    <VersionInfo>
        <Version>1.0</Version>
        <LoginUrl>http://my.vcloud.com/api/v1.0/login</LoginUrl>
        <MediaTypeMapping> ... </MediaTypeMapping>
        ...
    </VersionInfo>
    ....
</SupportedVersions>

Now user needs to fetch the log in URL and perform the log in operation. Which in turn returns a list of 'Reference' to all the Organizations available to this user to access.

<OrgList  ...>
    <Org type="application/vnd.vmware.vcloud.org+xml" name="my-org2" href="https://my.vcloud.com/api/v1.0/org/537058365"/>
    <Org type="application/vnd.vmware.vcloud.org+xml" name="my-org1" href="https://my.vcloud.com/api/v1.0/org/1041520205"/>
</OrgList>
You must have realized by now that the above are refrences/links to the Organization resources. They are not the actual resources. SO we get the URL for the Organization using the 'href' attribute and perfrom the GET operation on it. Notice in following response that the resource provides link to itself as well.

e.g. GET https://my.vcloud.com/api/v1.0/org/537058365
This is of the form https://<server>/api/v1.0/org/{id}. One of the other tenet of HATEOS implemented by vCLoud API is that the URL are opaque. Which means client is discouraged to cache these URL and rely instead on the 'href' and links.

Now lets look into the Organization resource in response to above request
<Org xmlns="http://www.vmware.com/vcloud/v1" name="my-org2" type="application/vnd.vmware.vcloud.org+xml" href="https://my.vcloud.com/api/v1.0/org/537058365" ... >
    <Link rel="down" type="application/vnd.vmware.vcloud.vdc+xml" name="org2_vdc1" href="https://my.vcloud.com/api/v1.0/vdc/1700638305"/>
    <Link rel="down" type="application/vnd.vmware.vcloud.tasksList+xml" href="https://my.vcloud.com/api/v1.0/tasksList/537058365"/>
    <Description>my-org2</Description>
    <FullName>my-org2</FullName>
</Org>

The difference in this response to note is the 'Link' element. This element provides further navigation paths. Specifically how to access the TaskList resource and the vDC resource contained in this Organization. (refer to the UML diagram in my earlier post for detailed relationsships between resources.) Another point to note is the 'rel' attribute. In addition to just giving the navigation paths it also provides the relationsship between this resource and the linked resource using the 'rel' attribute. for example the 'down' indicates containment such that this resource contains the linked resource.

The Link with 'rel' attribute also indicates what actions can be perfromed on this resource. Following Link from the 'Vdc' indicates that we can upload a vApp Template using the URL associated with it.

<Link rel="add" type="application/vnd.vmware.vcloud.uploadVAppTemplateParams+xml" href="https://my.vcloud.com/api/v1.0/vdc/1700638305/action/uploadVAppTemplate"/>
And when it comes to resources like vApp we indicate the available actions as following. This vApp gives out the link to power it off and also indicates what type of relationship (actionin this case) the Link has with the resource.
<VApp ... >
    <Link rel="power:powerOff" href="https://my.vcloud.com/api/v1.0/vApp/vapp-1299560622/power/action/powerOff"/>
    ...
</VApp>

The vCloud API provides only links that are relevant to the curent state of the resource. For example the above link in vApp will only be available if the vApp is in poer on state. If the vApp is powered off then there will be corresponding link to power on operation.

so in conclusion we just saw how the vCloud API adheres to the third level of REST maturity but while doing so we also saw how we can navigate the vCloud resources. Let me promise you one thing, this blog post would be much smaller if I avoid using those XML examples, and you know what it will make your code also very small, readable and maintainable if some one else takes care of those XML and HTTP verbs such as GET/POST. We will see how the SDK released along with the vCloud API can make our life easy in subsequent posts. 

No comments:

Post a Comment