Spring Data REST is a Spring module that automatically creates RESTful APIs for Spring Data repositories. It eliminates boilerplate code, allowing you to focus on your application’s core logic.

Benefits:

  • Reduced Boilerplate: No need to write controllers for CRUD operations.
  • Hypermedia-Driven: APIs are discoverable through links (HAL).
  • Customization: Fine-tune the API’s behavior using configuration or annotations.

Implementation:

  1. Project Setup: Create a Spring Boot project with Spring Data REST and your database dependency.

  2. Entity:

@Entity
public class Book {
    @Id
    @GeneratedValue
    private Long id;
    private String title;
    private String author;
    // getters and setters
}
  1. Repository:
@RepositoryRestResource
public interface BookRepository extends JpaRepository<Book, Long> {
}

API Endpoints (Book):

  • GET /books (List all books with pagination, sorting, and filtering):

    • Input:

      • page (optional): Page number (default: 0)
      • size (optional): Page size (default: 20)
      • sort (optional): Sorting criteria (e.g., title,asc or author,desc)
      • title (optional): Filter by title (substring match)
      • author (optional): Filter by author (substring match)
    • Output:

{
  "_embedded": {
    "books": [
      {
        "title": "The Hitchhiker's Guide to the Galaxy",
        "author": "Douglas Adams",
        "_links": {
          "self": { "href": "/books/1" },
          "book": { "href": "/books/1" }
        }
      },
      // ... more books
    ]
  },
  "_links": {
    "self": { "href": "/books?page=0&size=20" },
    "first": { "href": "/books?page=0&size=20" },
    "prev": { "href": "/books?page=0&size=20" }, // if applicable
    "next": { "href": "/books?page=1&size=20" }, // if applicable
    "last": { "href": "/books?page=5&size=20" }, // if applicable
    "profile": { "href": "/profile/books" }
  },
  "page": {
    "size": 20,
    "totalElements": 100,
    "totalPages": 5,
    "number": 0
  }
}
  • GET /books/{id} (Get a book by ID):

    • Input: Book ID (e.g., /books/1)
    • Output:
{
    "title": "The Hitchhiker's Guide to the Galaxy",
    "author": "Douglas Adams",
    "_links": {
        "self": { "href": "/books/1" },
        "book": { "href": "/books/1" }
    }
}
  • POST /books (Create a new book):

    • Input:
{
    "title": "The Hitchhiker's Guide to the Galaxy",
    "author": "Douglas Adams"
}
  • Output:
{
    "title": "The Hitchhiker's Guide to the Galaxy",
    "author": "Douglas Adams",
    "_links": {
        "self": { "href": "/books/1" },
        "book": { "href": "/books/1" }
    }
}
  • PUT /books/{id} (Update a book):

    • Input: Book ID and updated data (e.g., /books/1)
{
    "title": "The Restaurant at the End of the Universe",
    "author": "Douglas Adams"
}
  • Output: Updated book data (similar to GET output)

  • DELETE /books/{id} (Delete a book):

    • Input: Book ID (e.g., /books/1)
    • Output: 204 No Content

Viewing the API:

Spring Data REST provides a convenient way to explore your API using the HAL browser. After starting your application, navigate to http://localhost:8080 (or your configured port) in your web browser. This will open the HAL browser, allowing you to navigate through your API’s resources and their relationships.

Accessing the API from Postman:

  1. Open Postman: Launch the Postman application.
  2. Create a Request: Select the appropriate HTTP method (GET, POST, PUT, DELETE) and enter the API endpoint URL (e.g., http://localhost:8080/books).
  3. Set Headers (if required): For POST and PUT requests, set the Content-Type header to application/json.
  4. Add Body (if required): For POST and PUT requests, enter the request data in JSON format.
  5. Send Request: Click the “Send” button to execute the request.
  6. View Response: The response from the API will be displayed in the Postman interface.

Integrating Other APIs and HAL Browser Visibility:

To incorporate additional APIs outside of Spring Data REST’s automatic generation:

  1. Create a Controller: Use Spring’s @RestController to define custom endpoints.
  2. Define Endpoints: Use @GetMapping, @PostMapping, etc., to map HTTP methods to controller methods.
  3. Handle Requests: Implement controller methods to process requests and return responses.
  4. HAL Browser Integration (Optional):
    • RepositoryLinksResource: Create a ResourceProcessor<RepositoryLinksResource> bean to add links to the root resource in the HAL browser.
    • ControllerLinkBuilder: Use ControllerLinkBuilder to generate links to your custom endpoints.

Example:

@RestController
@RequestMapping("/api")
public class CustomApiController {

    @GetMapping("/hello")
    public String sayHello() {
        return "Hello from custom API!";
    }
}

This creates a custom endpoint /api/hello that returns a simple string. By default, this endpoint will not be visible in the HAL browser. To make it visible, you need to add a ResourceProcessor<RepositoryLinksResource> bean to your project.

Generating OpenAPI Specification (JSON):

To get the entire API as an OpenAPI JSON specification, you can use the springdoc-openapi library.

  1. Add Dependency: Add the springdoc-openapi-ui dependency to your project.
  2. Access OpenAPI Endpoint: Access the generated OpenAPI specification at http://localhost:8080/v3/api-docs (replace 8080 with your configured port).

Conclusion:

Spring Data REST is a powerful tool for rapid REST API development, particularly for data-centric applications. It’s easy to integrate custom APIs alongside Spring Data REST to provide additional functionality. While custom endpoints won’t automatically appear in the HAL browser, you can explicitly add them using a ResourceProcessor<RepositoryLinksResource> for seamless integration. Additionally, generating the OpenAPI specification allows easy integration with API documentation and testing tools.


Discover more from GhostProgrammer - Jeff Miller

Subscribe to get the latest posts sent to your email.

By Jeffery Miller

I am known for being able to quickly decipher difficult problems to assist development teams in producing a solution. I have been called upon to be the Team Lead for multiple large-scale projects. I have a keen interest in learning new technologies, always ready for a new challenge.