Giter Club home page Giter Club logo

angular-hateoas's Introduction

angular-hateoas

An AngularJS module for using $resource with a HATEOAS-enabled REST API.

What is HATEOAS?

HATEOAS, which stands for Hypermedia as the Engine of Application State, is a type of REST architecture that enables enhanced decoupling of server and client. The basic idea is that with every response, the server provides a list of endpoints (or "links") to perform actions or retrieve information related to the data in the response.

Why HATEOAS?

The use of HATEOAS can allow the client to be completely indifferent to the REST structure of the API, and instead rely on knowledge of relationships between objects. In many cases this can result in a more logical client application flow, as well as the opportunity for the server to evolve independently from the client application without disrupting functionality.

What does this module do?

Angular does not have a built-in way to cleanly navigate a HATEOAS-style API — the $resource object was created to consume traditional service-based endpoints, plugging in variables as needed to account for relationships between objects.

For instance, a traditional approach might look like this:

var personResource = $resource("/api/people/:personId");
var addressResource = $resource("/api/people/:personId/addresses");

var people = personResource.query(null, function () {
	var firstPerson = people[0];
	var firstPersonAddresses = addressResource.query({ personId: person[i].personId }, function () {
		console.log(firstPersonAddresses);
	});
});

This is a very simplified example, but notice the arbitrary information that the front-end developer needs to know about how to get an address for a person: you need to know where the addresses endpoint is, and you need to know what to pass in to the call to get it (personId).

Compare this to the HATEOAS approach, where the server delivers links to related endpoints:

var personResource = $resource("/api/people/:personId");

var people = personResource.query(null, function () {
	var firstPerson = people[0];
	var firstPersonAddresses = firstPerson.resource("addresses").query(null, function () {
		console.log(firstPersonAddresses);
	});
});

The angular-hateoas module creates an application-wide interceptor to automatically add the resource method to all HATEOAS responses. Alternatively, you could transform a response manually:

var personResource = $resource("/api/people/:personId");

var people = personResource.query(null, function () {
	var firstPerson = people[0];
	var firstPersonAddresses = new HateoasInterface(firstPerson).resource("addresses").query(null, function () {
		console.log(firstPersonAddresses);
	});
});

Usage

To start, make sure you are including angular-hateoas.js in your JavaScript compiler (or the minified version on your page), and add hateoas as a dependency in your application module declaration:

var app = angular.module("your-application", ["ngResource", "hateoas"]);

To enable the global interceptor, invoke HateoasInterceptorProvider.transformAllResponses() in a config block:

app.config(function (HateoasInterceptorProvider) {
	HateoasInterceptorProvider.transformAllResponses();
});

And that's it! All HATEOAS-enabled responses will allow you to retrieve related resources as you need them:

var item = $resource("/api/path/to/item").get(null, function () {
	console.log("Here's a related $resource object: ", item.resource("some-related-endpoint"));
});

// also works with array results from $resource(...).query()
var items = $resource("/api/path/to/items").query(null, function () {
	angular.forEach(items, function (item) {
		console.log("Here's a related $resource object: ", item.resource("some-related-endpoint"));
	});
});

You can also instantiate HateoasInterface directly if you prefer not to use an application-wide interceptor. Simply inject HateoasInterface where you need it and instantiate a new instance, passing in the raw response data as seen in the previous section.

Options

The HateoasInterfaceProvider allows for some basic configuration.

Setting the links key

By default, HateoasInterface parses the HATEOAS links from an object with the key "links" within the response data. This key can be changed using setLinksKey:

app.config(function (HateoasInterfaceProvider) {
	HateoasInterfaceProvider.setLinksKey("related");
	// HateoasInterface will now search response data for links in a property called "related"
});

Setting $resource options

Angular's $resource object accepts two optional parameters, as seen in the documentation: paramDefaults and actions. These parameters can be passed directly in to the $resource constructor from the HateoasInterface.resource method:

var relatedResource = someHateoasItem.resource("some-related-endpoint", {
	binding: "value"
}, {
	update: {
		method: "PUT"
	}
});

For more information about these parameters, refer to Angular's $resource documentation.

The custom HTTP actions can also be set to an application-wide default, which can be useful if you're using the same actions/methods throughout your app:

app.config(function (HateoasInterfaceProvider) {
	HateoasInterfaceProvider.setHttpMethods({
		update: {
			method: "PUT"
		}
	});
});

About

The angular-hateoas module was created for a personal need, and while it is working for my own projects, it is still in a very early stage of development and probably won't fit every HATEOAS developer's needs. Feel free to use and enjoy – while I can't guarantee support, I welcome any comments, forks, pull requests, bug reports, etc.

angular-hateoas was built to work with Spring Hateoas, and has yet to be tested in other environments.

Related Projects

angular-spring-data-rest — based on angular-hateoas but designed specifically to consume Spring Data REST responses rather than vanilla HATEOAS objects

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.