angular-hy-res v0.0.34
angular-hy-res 
A hypermedia client/library for AngularJS. HAL, Siren, and Link header extensions are included by default, but support for other media types can be added. angular-hy-res is an thin AngularJS wrapper around the core hy-res library.
Support
For any questions, please post to the AngularHyRes Google Group.
Installation
Bower
angular-hy-res is available via Bower. To install:
$ bower install --save angular-hy-res
NPM
angular-hy-res is also published as an node module w/ NPM. To install:
$ npm install --save angular-hy-res
It is recommended to use it along with Browserify or Webpack.
Note: The API is still evolving, so during the 0.0.x series of releases there are no API stability guarantees Those users needed a stable API should set an explicit version in bower.json
Manual
Download the production version or the development version.
In your web page:
<script src="angular.js"></script>
<script src="dist/angular-hy-res-full.min.js"></script>
Documentation
angular-hy-res offers an alternative to the built in AngularJS $resource
service that focuses on using hypermedia
controls, links (and/or embedded resources) discovered by link relation, to traverse a hypermedia enabled API.
Note: For more documentation, refer to the full API documentation
for the core hy-res
library.
The core of angular-hy-res is found in the hrCore
AngularJs module. To enable it, add that module to your own
module definition. In addition, if you want to use the Collection+JSON, HAL, Siren, or Link header integration,
you must include the hrCollectionJson
, hrHal
, hrSiren
, or hrLinkHeader
modules:
angular.module('myApp', [
'hrCore',
'hrCollectionJson',
'hrHal',
'hrSiren',
'hrLinkHeader',
'hrJson'
]);
The hrJson
module handles data for simple application/json
responses, with no additional
hypermedia controls present.
In the future, integration with other hypermedia formats, e.g. Uber, JSON-LD, will be available in their own modules.
hrRoot
Most hypermedia APIs are accessed by fetching the API root from a well known URL, and then following links from there
to do any further interactions. The main entry point to angular-hy-res
is the hrRoot
service, which allows you
to fetch a resource for the API root. The easiest way to do this is to inject the root in the $routeProvider
:
$routeProvider
.when('/posts', {
resolve: {
root: function(hrRoot) {
return hrRoot('/api').follow().$promise;
}
}
};
Note: We are using the $promise
property of a resource to keep the route from resolving until the root is fully fetched.
hrRoot(url)
Returns a hrWebLink
that can be followed to retrieve the root hy-res Resource
. See Resource
for details on the API available once once you have retrieved the root.
Collection+JSON Extension
By default, the Collection+JSON extension will only process links and embedded resources in responses if the HTTP response
Content-Type
header equals application/vnd.collection+json
. If you have a custom media type that extends Collection+JSON, you can register
it with with the hrCollectionJsonExtensionProvider
in the mediaTypes
array:
angular.module('myModule', ['hrCollectionJson'])
.config(function(hrCollectionJsonExtensionProvider) {
hrSirenExtensionProvider.mediaTypes.push('application/vnd.myco.mytype');
});
Collection+JSON queries are exposed as forms, and can be accessed using Resource#$form
or Resource#$forms
. For adding items, a form is accessible using the
create-form
IANA standard link relation.
Collection items can be extracted using the item
standard link relation using
Resource#$sub
or Resource#$subs
.
A given embedded item can be edited by using the form with the edit-form
standard
link relation.
HAL Extension
By default, the HAL extension will only process links an embedded resources in responses if the HTTP response
Content-Type
header equals application/hal+json
. If you have a custom media type that extends HAL, you can register
it with with the hrHalExtensionProvider
in the mediaTypes
array:
angular.module('myModule', ['hrHal'])
.config(function(hrHalExtensionProvider) {
hrHalExtensionProvider.mediaTypes.push('application/vnd.myco.mytype');
});
Siren Extension
By default, the Siren extension will only process links an embedded resources in responses if the HTTP response
Content-Type
header equals application/vnd.siren+json
. If you have a custom media type that extends Siren, you can register
it with with the hrSirenExtensionProvider
in the mediaTypes
array:
angular.module('myModule', ['hrSiren'])
.config(function(hrSirenExtensionProvider) {
hrSirenExtensionProvider.mediaTypes.push('application/vnd.myco.mytype');
});
At this point, the Siren extension includes both the Siren links
and the sub-entity embedded links in the set
queried by the $link
function of hrResource
.
Text Extension
The text extension handles responses with text content types, and exposes the text response
as a text
property on the resolved resource. By default, the text extension will only process responses if
the HTTP response Content-Type
header equals text/plain
. If you would like other text
subtypes to be handled,
you can register it with with the hrTextExtensionProvider
in the subTypes
array:
angular.module('myModule', ['hrText'])
.config(function(hrTextExtensionProvider) {
hrTextExtensionProvider.subTypes.push('rtf');
});
Alternately, if you would like the extension to handle all text subtypes, the extension can be configured to be in 'wildcard' mode:
angular.module('myModule', ['hrText'])
.config(function(hrTextExtensionProvider) {
hrTextExtensionProvider.wildcard = true;
});
By doing so, HTTP requests will include a wildcard in the Accept
header, e.g. text/*
,
and the extension will handle any responses with a Content-Type
of the text
primary media type.
Examples
A complete working example can be found at angular-hy-res-example, which demonstrates the below pagination concept. A public copy is deployed to Heroku at:
https://angular-hy-res-example.herokuapp.com/
For example, given a HAL collection resource that uses the standard link relations next
and prev
to control
paging through the collection, and the item
relation for each item in the collection, here is a sample response:
{
"_links": {
"self": { "href": "/page/2" },
"next": { "href": "/page/3" },
"prev": { "href": "/page/1" }
},
"_embedded": {
"item": [
{
"_links": { "self": { "href": "/posts/123" } },
"title": "MY blog post",
"tags": [ "blogging", "hypermedia" ]
}
]
}
}
Then the controller can easily be:
angular.module('angularHyResDocs')
.controller('ahrdPageCtrl', function(root) {
$scope.page = root.$followOne('http://api.myserver.com/rel/posts');
$scope.posts = $scope.page.$followAll('item');
var follow = function(rel) {
$scope.page = $scope.page.$followOne(rel);
$scope.posts = $scope.page.$followAll('item');
};
$scope.next = function() {
if (!$scope.hasNext()) {
return;
}
follow('next');
};
$scope.prev = function() {
if (!$scope.hasPrev()) {
return;
}
follow('prev');
};
$scope.hasNext = function() {
return $scope.page.$has('next');
};
$scope.hasPrev = function() {
return $scope.page.$has('prev');
};
});
And the view:
<div>
<ul class="pagination">
<li>
<a ng-click="{{prev()}}" ng-class="{disabled: !hasPrev()}">«</a>
</li>
<li>
<a ng-click="{{next()}}" ng-class="{disabled: !hasNext()}">»</a>
</li>
</ul>
<ul>
<li ng-repeat="post in posts">{{post.title}}</li>
</ul>
</div>
Another complete working example can be found at pollsApiClient, which uses most of library features, such as actions, links, pagination, link following and so on. A public copy is deployed to Heroku at:
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago