Skip to content

Instantly share code, notes, and snippets.

@smizell
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save smizell/8565f6576ac34d3185b9 to your computer and use it in GitHub Desktop.
Save smizell/8565f6576ac34d3185b9 to your computer and use it in GitHub Desktop.

Recursive HAL

There are a few steps you can take to simplify HAL even more than it is by making links recursive resources. It requires these changes.

  1. Add a _href property to be used to specify the URI of the resource. This would replace using self links.
  2. Change templated to _templated
  3. Change hreflang to _hreflang
  4. Change title to _title
  5. Consider links to be full HAL objects
{
  "_href": "/orders",
  "currentlyProcessing": 14,
  "shippedToday": 20,
  "_links": {
    "curies": [
      { 
        "name": "ea",
        "_href": "http://example.com/docs/rels/{rel}",
        "_templated": true
      }
    ],
    "next": { 
      "_href": "/orders?page=2"
    },
    "ea:find": {
      "_href": "/orders{?id}",
      "_templated": true
    },
    "ea:admin": [
      {
        "_href": "/admins/2",
        "_title": "Fred"
      },
      {
        "_href": "/admins/5",
        "_title": "Kate"
      }
    ],
    "ea:order": [
      {
        "_href": "/orders/123",
        "_links": {
            "ea:basket": { "_href": "/baskets/98712" },
            "ea:customer": { "_href": "/customers/7809" }
        },
        "total": 30.00,
        "currency": "USD",
        "status": "shipped"
      },
      {
        "_href": "/orders/124",
        "_links": {
            "ea:basket": { "_href": "/baskets/97213" },
            "ea:customer": { "_href": "/customers/12369" }
        },
        "total": 20.00,
        "currency": "USD",
        "status": "processing"
      }
    ]
  }
}

Benefits

This allows for several simplifications.

Remove Embedded

Since every link has all the capabilities of any HAL resource, there is no need to have _embedded.

Remove Special Link Properties

The profile and deprecation properties can simply become links with link relations

{
  "_links": {
    "order": {
      "_links": {
        "profile": { "_href": "http://example.com/profile" }
      }
    }
  }
}

Remove Name Property

The name property is unnecessary, as any property can be included. Below shows email being used to differentiate between customer links.

{
  "_links": {
    "customer": [
      {
        "email": "jane@example",
        "_href": "/customers/4",
        "_links": {
          "profile": { "_href": "http://example.com/profile" }
        }
      },
      {
        "email": "john@example",
        "_href": "/customers/5",
        "_links": {
          "profile": { "_href": "http://example.com/profile" }
        }
      }
    ]
  }
}

Meta

Some of these items could be moved to a _meta property. The only underscored properties would be _href, _links, and _meta.

{
  "_meta": {
    "title": "Customer List",
    "curies": [{
      "name": "ea",
      "href": "http://example.com/{rel}"
    }]
  },
  "_links": {
    "ea:find": {
      "_meta": {
        "templated": true,
        "hreflang": "en"
      },
      "_href": "/orders{?id}"
    },
    "ea:customer": [
      {
        "email": "jane@example",
        "_href": "/customers/4",
        "_links": {
          "profile": { "_href": "http://example.com/profile" }
        }
      },
      {
        "email": "john@example",
        "_href": "/customers/5",
        "_links": {
          "profile": { "_href": "http://example.com/profile" }
        }
      }
    ]
  }
}

This would allow more special properties to be added without polluting the object with underscored properties.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment