What You'll Learn

Up to this point, we've been building an application that builds its HTML on the server-side and sends across the network to the browser. This was the dominant model for many years. There are advantages and disadvantages to this approach, especially when combined with caching and proxies that serve static content. There may be a delay before the page arrives, but the page is typically useable in short time.

The modern preference for web applications is for the server to manage the domain and to offer APIs (Application Pprogramming Interfaces) that serve data and handle events/commands. The user interface is programming in a client-side technology which is typically JavaScript and further, which typically uses a client-side, JavaScript framework such as Angular, Vue.js, React, Svelte or Web Components. Web Assembly is another option. APIs are often seen as products in their own right as they enable others to build their own applications on top of the API and/or to integrate their applications.

For example, in our application, a charity may choose to direct donors to our website, but they could use an API to populate their own web pages with the total raised via our platform.

Equally, our application might consume an API provided by the government to calculate GiftAid.

RESTful Web Services

The most common form of API at present is the RESTful web service. This form of API follows the REST principles and typically uses HTTP(s) and JSON as the protocol for data transfer. REST will be covered in other parts of the programme content.

We'll now implement a simple RESTful web service in Spring Boot.

Let's expose the list of charities as a REST service. We'll reuse the service layer and return JSON data.

Create a new package api.controllers (check the repository if you're not sure about levels here).

Then, create a new class CharitySearchAPIController.java.

In CharitySearchAPIController

@RestController
@RequestMapping("api")
public class CharitySearchAPIController {

    private CharitySearch charitySearch;

    public CharitySearchAPIController(CharitySearch aCharitySearch) {
        charitySearch = aCharitySearch;
    }

    @GetMapping("charities")
    public ResponseEntity<List<CharityDTO>> findAll() {
        return ResponseEntity.ok(charitySearch.findAll());
    }
}

A lot of this should now be familiar.

There are some new elements as well.

The "controller" is annotated with @RestController. This is not the same as a @Controller because, rather than return a view or redirect, this will return data directly.

So the next part to turn our attention to is the return type of the method. This is ResponseEntity>. Since we are using REST over HTTP, the status codes and headers are just as important as the body. ResponseEntity provides a wrapper around the body data and allows us to set these other parts of the return data.

In our example, we're returning the list of CharityDTO objects. We don't have any error checking so we'll assume that the HTTP Status Code is always 200 (OK)... for now!

To return the data, we create a ResponseEntity using the of static method and pass in the returned list from the service. Nowhere in this code do we explicitly handle HTTP abstractions and nowhere in this code do we manually produce JSON. These low-level concerns are handled for us when control passes back to the framework. Remember, our controller will be called by the framework and therefore, control will return back to the framework.

Go to a browser and browse to localhost:8080/api/charities.

(Alternatively, use a tool like Postman).

You should see a JSON representation of the charity data and you should be able to see a 200 response code in the browser developer tools (or in Postman's response data).

In this tutorial, we have created a very simple RESTful API in order to demonstrate dynamic content.

We have reused the existing service layer. There will be times when the different uses by different clients could drive us to design different service abstraction levels (i.e. there may be a time when we want to return more than just the basic charity data).