Partner – Microsoft – NPI (cat= Spring)
announcement - icon

Azure Spring Apps is a fully managed service from Microsoft (built in collaboration with VMware), focused on building and deploying Spring Boot applications on Azure Cloud without worrying about Kubernetes.

And, the Enterprise plan comes with some interesting features, such as commercial Spring runtime support, a 99.95% SLA and some deep discounts (up to 47%) when you are ready for production.

>> Learn more and deploy your first Spring Boot app to Azure.

You can also ask questions and leave feedback on the Azure Spring Apps GitHub page.

Course – LS (cat=REST)

Get started with Spring and Spring Boot, through the reference Learn Spring course:


1. Overview

In this tutorial, we’ll be discussing what HAL is and why it’s useful, before introducing the HAL browser.

We’ll then use Spring to build a simple REST API with a few interesting endpoints and populate our database with some test data.

Finally, using the HAL browser, we’ll explore our REST API and discover how to traverse the data contained within.

2. HAL and the HAL Browser

JSON Hypertext Application Language, or HAL, is a simple format that gives a consistent and easy way to hyperlink between resources in our API. Including HAL within our REST API makes it much more explorable to users as well as being essentially self-documenting.

It works by returning data in JSON format which outlines relevant information about the API.

The HAL model revolves around two simple concepts.

Resources, which contain:

  • Links to relevant URIs
  • Embedded Resources
  • State


  • A target URI
  • A relation, or rel, to the link
  • A few other optional properties to help with depreciation, content negotiation, etc

The HAL browser was created by the same person who developed HAL and provides an in-browser GUI to traverse your REST API.

We’ll now build a simple REST API, plug in the HAL browser and explore the features.

3. Dependencies

Below is the single dependency needed to integrate the HAL browser into our REST API. You can find the rest of the dependencies for the API in the GitHub code.

Firstly, the dependency for Maven-based projects:


If you’re building with Gradle, you can add this line to your build.gradle file:

compile group: '', name: 'spring-data-rest-hal-explorer', version: '3.4.1.RELEASE'

4. Building a Simple REST API

4.1. Simple Data Model

In our example, we’ll be setting up a simple REST API to browse different books in our library.

Here, we define a simple book entity which contains appropriate annotations so that we can persist the data with Hibernate:

public class Book {

  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private long id;

  @Column(columnDefinition = "VARCHAR", length = 100)
  private String title;

  @Column(columnDefinition = "VARCHAR", length = 100)
  private String author;

  @Column(columnDefinition = "VARCHAR", length = 1000)
  private String blurb;

  private int pages;

  // usual getters, setters and constructors


4.2. Introducing a CRUD Repository

Next, we’ll need some endpoints. To do this, we can leverage the PagingAndSortingRepository and specify that we want to get data from our Book entity.

This Class provides simple CRUD commands, as well as paging and sorting capabilities right out of the box:

public interface BookRepository extends PagingAndSortingRepository<Book, Long> {

    @RestResource(rel = "title-contains", path="title-contains")
    Page<Book> findByTitleContaining(@Param("query") String query, Pageable page);

    @RestResource(rel = "author-contains", path="author-contains", exported = false)
    Page<Book> findByAuthorContaining(@Param("query") String query, Pageable page);

If this looks a bit strange, or if you’d like to know more about Spring Repositories, you can read more here.

We’ve extended the repository by adding two new endpoints:

  • findByTitleContaining – returns books that contain the query included in the title
  • findByAuthorContaining – returns books from the database where the author of a book contains the query

Note that our second endpoint contains the export = false attribute. This attribute stops the HAL links being generated for this endpoint, and won’t be available via the HAL browser.

Finally, we’ll load our data when Spring is started by defining a class which implements the ApplicationRunner interface. You can find the code on GitHub.

5. Installing the HAL Browser

The setup for the HAL browser is remarkably easy when building a REST API with Spring. As long as we have the dependency, Spring will auto-configure the browser, and make it available via the default endpoint.

All we need to do now is press run and switch to the browser. The HAL browser will then be available on http://localhost:8080/

6. Exploring Our REST API With the HAL Browser

The HAL browser is broken down into two parts – the explorer and the inspector. We’ll break down and explore each section separately.

6.1. The HAL Explorer

As it sounds, the explorer is devoted to exploring new parts of our API relative to the current endpoint. It contains a search bar, as well as text boxes to display Custom Request Headers and Properties of the current endpoint.

Below these, we have the links section and a clickable list of Embedded Resources.

If we navigate to our /books endpoint we can view the existing links:


These links are generated from the HAL in the adjacent section:

"_links": {
    "first": {
      "href": "http://localhost:8080/books?page=0&size=20"
    "self": {
      "href": "http://localhost:8080/books{?page,size,sort}",
      "templated": true
    "next": {
      "href": "http://localhost:8080/books?page=1&size=20"
    "last": {
      "href": "http://localhost:8080/books?page=4&size=20"
    "profile": {
      "href": "http://localhost:8080/profile/books"
    "search": {
      "href": "http://localhost:8080/books/search"

If we move to the search endpoint, we can also view the custom endpoints we created using the PagingAndSortingRepository:

  "_links": {
    "title-contains": {
      "href": "http://localhost:8080/books/search/title-contains{?query,page,size,sort}",
      "templated": true
    "self": {
      "href": "http://localhost:8080/books/search"

The HAL above shows our title-contains endpoint displaying suitable search criteria. Note how the author-contains endpoint is missing since we defined that it should not be exported.

6.3. Viewing Embedded Resources

Embedded Resources show the details of the individual book records on our /books endpoint. Each resource also contains its own Properties and Links section:


6.4.  Using Forms

The question mark button in the GET column within the links section denotes that a form modal can be used to enter custom search criteria.

Here is the form for our title-contains endpoint:

The HAL browser selection form

Our custom URI returns the first page of 20 books where the title contains the word ‘Java’.

6.5. The Hal Inspector

The inspector makes up the right side of the browser and contains the Response Headers and Response Body. This HAL data is used to render the Links and Embedded Resources that we saw earlier in the tutorial.

7. Conclusion

In this article, we’ve summarised what HAL is, why it’s useful and why it can help us to create superior self-documenting REST APIs.

We have built a simple REST API with Spring which implements the PagingAndSortingRepository, as well as defining our own endpoints. We’ve also seen how to exclude certain endpoints from the HAL browser.

After defining our API, we populated it with test data and explored it in detail with the help of the HAL browser. We saw how the HAL browser is structured, and the UI controls which allowed us to step through the API and explore its data.

As always, the code is available over on GitHub.

Course – LS (cat=Spring)

Get started with Spring and Spring Boot, through the Learn Spring course:

Course – LS (cat=REST)

Get started with Spring and Spring Boot, through the Learn Spring course :

res – REST (eBook) (cat=REST)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.