Download EPUB

Book Summary: RESTful Web Clients

fagnerbrack.com 3 min read Original article
Summary
This summary covers key ideas from "RESTful Web Clients," a book about building web clients that consume RESTful services using hypermedia and web standards.

The book stresses REST as an architectural style for distributed systems, based on Roy Fielding's dissertation, not the common RPC-over-HTTP-with-JSON style seen in practice. It explains resources, representations, and hypermedia-driven clients that adapt to API changes without code updates.

It highlights reuse through standard web tech like HTML, CSS, and JavaScript, and shows patterns and anti-patterns. One pattern uses query-based navigation of hypermedia controls instead of hardcoded response indexes. Custom clients can handle multiple media types through content negotiation, like HAL JSON and HTML.

Developers get guidance to build flexible, maintainable, reusable clients for services inside and outside their organization.

“RESTful Web Clients: Enabling Reuse Through Hypermedia” provides insights into designing and building RESTful web clients that effectively consume and interact with web services. The book emphasizes the importance of leveraging hypermedia and existing web standards to create reusable and flexible clients.

It talks about REST as an Architectural Style for Distributed Systems based on Roy Fielding's Dissertation, not the way REST is used in the wild, which is RPC over HTTP using JSON.

DISCLAIMER: The code examples are not taken from the book.

The most valuable points from the book are:

Understanding RESTful Web Services

The book starts by providing a solid understanding of RESTful web services, focusing on the concepts of resources, representations, and hypermedia.

Hypermedia-Driven Web Clients

Mike emphasizes the importance of designing web clients that are driven by hypermedia, allowing them to adapt to changes in the web service without requiring updates.

For example, a web client uses hypermedia controls provided by the web service to navigate through resources and perform actions, ensuring that the client can adapt to changes in the API without breaking.

// Control response for media types with +json suffix
{
actions: [{
name: 'prev',
target: 'http://server.com/resource-a',
method: 'POST'
}, {
name: 'next',
target: 'http://server.com/resource-b',
method: 'PUT'
}]
};

Leveraging Web Standards

The book highlights the importance of using existing web standards such as HTML, CSS, and JavaScript to build RESTful web clients, enabling reuse and reducing development effort.

For example, a developer builds a web client using HTML and JavaScript, allowing it to be used across various platforms and devices without the need for additional development.

<!-- Navigation interception using Code on Demand -->
<script>
[...document.querySelectorAll('form')].forEach((action) => {
action.addEventListener('submit', (event) => {
event.preventDefault();
// Custom handling of navigation
});
});

</script>

<!-- Control response for text/html media type -->
<form name="prev" method="POST" action="http://server.com/resource-a">
<button type="submit"></button>
</form>
<form name="next" method="POST" action="http://server.com/resource-b">
<button type="submit"></button>
</form>

Web Client Patterns and Anti-Patterns

The author discusses various patterns and anti-patterns for building RESTful web clients, helping developers avoid common pitfalls and build more robust and maintainable clients.

For example, a developer learns to avoid tightly coupling the web client to a specific API structure, ensuring that the client remains flexible and adaptable to changes in the web service.

const response = {
actions: [{
name: 'prev',
target: 'http://server.com/resource-a',
method: 'POST'
}, {
name: 'next',
target: 'http://server.com/resource-b',
method: 'PUT'
}]
};

// This:
const query = queriable(response);
const action = {
url: query('actions[name="prev"]->["target"]') || '' // self,
method: query('actions[name="prev"]->["method"]') || 'GET'
};
const response = await fetch(action);

// Instead of this:
const action = {
url: response.actions[0].target,
method: response.actions[0].method
};
const response = await fetch(action);

Building Custom Web Clients

The book provides guidance on building custom web clients that can work with different media types and hypermedia controls, increasing the reusability and flexibility of the clients.

For example, a developer creates a custom web client that can handle various media types through Content Negotiation, such as XML and JSON, allowing it to work with different web services without requiring significant modification.

const HALResponse = await fetch({
...
headers: {
'Accept': 'application/hal+json'
}
});
const HTMLResponse = await fetch({
...
headers: {
'Accept': 'text/html'
}
});

By applying the concepts and best practices presented in “RESTful Web Clients: Enabling Reuse Through Hypermedia,” developers can build more flexible, maintainable, and reusable web clients that effectively interact with RESTful web services inside and outside an organization.