DEV Community

Fagner Brack
Fagner Brack

Posted on • Originally published at fagnerbrack.com on

Book Summary: RESTful Web Clients - Enabling Reuse Through Hypermedia

by Mike Amundsen

“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'
  }]
};
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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'
  }
});
Enter fullscreen mode Exit fullscreen mode

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.

Thanks for reading. If you have feedback, contact me on Twitter, LinkedIn or Github.

Top comments (0)