Designing and Developing a Search API with Spring Boot

Solutions Architect | Product Design & Development | Cloud-Native Microservices | Distributed Applications (Back-End)
Search for a command to run...

Solutions Architect | Product Design & Development | Cloud-Native Microservices | Distributed Applications (Back-End)
No comments yet. Be the first to comment.
Introduction to API Versioning: Why It Matters Imagine, You have developed an API and pushed your changes to the production. Now it is consumed by thousands of users across various different clients. The API is functioning well and business has decid...

What is so crucial about HTTPs in today's digital landscape that most websites mandate its use? In this article, we delve into the differences between HTTP and HTTPs. To understand better about this concept, let's explore the fundamentals of TLS/SSL ...

In this article, we are going to discuss on the best practices of RESTful API. Before we jump on to best practices, let's first understand what is REST and what makes an API RESTful. What is REST? REST is the most common communication standard betwee...

REST is the undisputed, go-to architecture for the vast majority of today's APIs. According to nordicapis.com, over 90% of the developers are using REST APIs. In this article let's understand what is REST and why it is so popular in developing web AP...

You've probably seen search features on most websites and apps these days. Most of these websites use a backend search API to fetch the results and display them to users. In this article, we're going to dive into how to design and develop a search API using Spring Boot.
We will take tutorials search as an example for the search API. At a high level, the tutorial search api takes a tutorial title as a search query and returns the relevant results in the response. Let’s discuss on the requirements and the desired functionality of the search api before we discuss on the API design.
Searching: The API should return data for the requested search query.
Sorting: The API should sort the data according to the client’s request. Sorting can be either ascending or descending order. By default, we will have Ascending sorting.
Pagination: The API should support pagination functionality as it is difficult to manage the data when there is a huge data.
Filter: Filtering can help narrow down the search results further.
Architectural Style: We will utilize REST architectural style as the search api is mainly resource-oriented and best suited for client and server communication.
Data format: When talking about data format, we will use JSON as it is easy to render in the client’s browser and also best suited for REST architectural style.
We will model the API to meet the functional requirements while following the best practices.
URL:
https://techstackengineer.com/api/v1/tutorials/search?query=java&page=0&size=10&sort=title&sortOrder=DSC
Base URL domain: “techstackengineer.com” shown here as a base url domain is for illustration purpose only. if you are running the code in your local, you can use localhost:{port} as a base domain.
Search Key: The “query” request parameter is used for passing the search key word.
Pagination: Fetching all the tutorials in a single API request when there are thousands of records may not effective. This can burden the server and results in a poor good user experience by displaying thousands of tutorials at once on the screen.
For this purpose, we can use “page” and “size” request parameters. page starts with 0 and we can choose size of each page as needed.
Sorting: Sorting is an additional feature that can be applied on any field in the search api. We can pass the sort field in “sort” request parameter and also choose to provide the “sortOrder.”
Our project structure will look similar to a typical spring boot project. You can use spring initializer https://start.spring.io/ to start creating a spring boot project.

Implementing the Controller:
First, let’s create TutorialController class using Spring annotations. The request parameters can be optional and be passed as needed to the search api.
@RestController
@RequestMapping("/api/v1/tutorials")
public class TutorialController {
@Autowired
TutorialService tutorialService;
@GetMapping("/search")
public ResponseEntity<SearchResponse> search(@RequestParam(required = false) String query,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size,
@RequestParam(required = false) String sort,
@RequestParam(required = false) String sortOrder,
@RequestParam(required = false) String filter,
@RequestParam(required = false) String category) {
RequestCriteria requestCriteria = new RequestCriteria(query, page, size, sort, sortOrder, filter, category);
Page<Tutorial> tutorialPage = tutorialService.findTutorialsByPagingAndSorting(requestCriteria);
SearchResponse searchResponse = new SearchResponse(tutorialPage.getContent(), tutorialPage.getTotalPages(),
tutorialPage.getTotalElements(), tutorialPage.getNumber());
return new ResponseEntity<>(searchResponse, HttpStatus.OK);
}
Configuring the Database: We will use the H2 in-memory database for our search api and below is the application.yml configuration.
spring:
application:
name: search-api
datasource:
url: jdbc:h2:mem:mydb
username: sa
password:
driverClassName: org.h2.Driver
h2:
console:
enabled: true
path: /console/
jpa:
database-platform: org.hibernate.dialect.H2Dialect
defer-datasource-initialization: true
#hibernate:
# ddl-auto: none
logging:
level:
root: INFO
Here, I am setting “defer-datasource-initialization” property to true. This will ensure that after hibernate schema creation is done, then additionally data.sql file will be executed. We are using “data.sql” file to load tutorials data during the application startup.
Defining the Tutorial Entity:
First, We will have a tutorial entity as our domain class.
@Entity
@Table(name = "tutorials")
public class Tutorial {
@Id
private Long id;
private String title;
private String description;
private String category;
private String publishedDate;
public Tutorial() {
}
}
Creating the Repository:
We will need a repository to access our tutorial entity. We can create tutorial repository by extending JpaRepository class.
Here, We are passing “Pageable” object to all the repository methods to achieve the pagination and sorting functionalities. These methods are used in different scenarios based on the input requests and results will contain a page object.
public interface TutorialRepository extends JpaRepository<Tutorial, Long> {
Page<Tutorial> findByTitleContainingIgnoreCase(String title, Pageable pageable);
Page<Tutorial> findByTitleContainingIgnoreCaseAndCategoryIgnoreCase(String title, String category,
Pageable pageable);
Page<Tutorial> findByCategoryIgnoreCase(String category, Pageable pageable);
}
Enhancing with Pagination and Sorting:
We can create PageRequest object by passing current page number and size (number of records)of the page. page number starts at 0.
PageRequest pageRequest = PageRequest.of(0, 10);
We can also do sorting along with pagination. This can be achieved by passing the sort object to the PageRequest as shown below.
The sort can be applied for any field like “title” or “description” as needed.
PageRequest pageRequest = PageRequest.of(0, 10, Sort.by(Sort.Direction.DESC, "title"));
Request:
http://localhost:8080/api/v1/tutorials/search?query=java&page=0&size=10&sort=title&sortOrder=ASC
Response:
{
"tutorials": [
{
"id": 96,
"title": "Java API Design",
"description": "Best practices for designing APIs in Java.",
"category": "Java",
"publishedDate": "2024-09-13"
},
{
"id": 1,
"title": "Java Basics",
"description": "Introduction to Java programming language.",
"category": "Java",
"publishedDate": "2024-01-15"
},
{
"id": 51,
"title": "Java Collections Framework",
"description": "Deep dive into Java Collections Framework.",
"category": "Java",
"publishedDate": "2024-09-13"
},
{
"id": 66,
"title": "Java Concurrency",
"description": "Understanding concurrency and multithreading in Java.",
"category": "Java",
"publishedDate": "2024-09-13"
},
{
"id": 82,
"title": "Java Functional Programming",
"description": "Introduction to functional programming in Java.",
"category": "Java",
"publishedDate": "2024-09-13"
}
],
"totalPages": 3,
"totalItems": 13,
"currentPage": 0
}
The spring boot project for this search api is available at below repo. Please check “search-api” module inside this repo.
https://github.com/techstackengineer/spring-boot-tutorials
Designing and developing a search API using Spring Boot involves understanding the key requirements such as searching, sorting, pagination, and filtering. By adopting a REST architectural style and utilizing JSON data format, we ensure efficient client-server communication.
The API model and contract are structured to meet functional needs while adhering to best practices.
Implementing features like pagination and sorting through Spring Boot's repository and PageRequest functionalities enhances the API's performance and user experience.
By following these guidelines, we can create robust and scalable search APIs that effectively handle large datasets and provide relevant search results to users.