Building RESTful APIs with Java Spring EASY!!!

Delirium
7 min readSep 4, 2023

--

In today’s interconnected digital world, the exchange of data between different software systems is essential. This exchange is made possible through Application Programming Interfaces, commonly known as APIs. In this guide, we will explore RESTful APIs and how to create them using Java Spring.

What is an API?

An API, or Application Programming Interface, is a set of rules and protocols that allow different software applications to communicate with each other. It defines the methods and data formats that applications can use to request and exchange information. APIs enable developers to access the functionality of other software systems and integrate them into their own applications.

1. Setup Your Development Environment:

Install Java Development Kit (JDK).

Set up an Integrated Development Environment (IDE) like IntelliJ IDEA or Eclipse. Or you can use Visual Studio Code with necessary extensions.

Install Apache Maven for managing project dependencies.

2. Create a Spring Boot Project:

Use Spring Initializr (https://start.spring.io/) or your IDE to create a new Spring Boot project. Select the necessary dependencies like Spring Web, Spring Data JPA, and Spring Boot DevTools.

3. Project Structure:

You should create your packages with classes(or interface) in it descendant or the same folder of the application class in the project. So Let’s start with controller class

Project tree suppose to look like this after you added controller, service, model and repository packages.

|-- src
| |-- main
| | |-- java
| | | |-- com
| | | | |-- example
| | | | | |-- myapp
| | | | | | |-- controller
| | | | | | | |-- UserController.java
| | | | | | |
| | | | | | |-- service
| | | | | | | |-- UserService.java
| | | | | | |
| | | | | | |-- model
| | | | | | | |-- User.java
| | | | | | |
| | | | | | |-- repository
| | | | | | | |-- UserRepository.java
| | | | | |
| | | | | |-- YourApplication.java
| | |
| |-- resources
| | |-- application.properties (or application.yml)
| |
|-- src
| |-- test
| | |-- java
| | | |-- com
| | | | |-- example
| | | | | |-- myapp
| | | | | | |-- controller
| | | | | | | |-- UserControllerTest.java
| | | | | | |
| | | | | | |-- service
| | | | | | | |-- UserServiceTest.java
| | | | | |
|-- pom.xml

1. Controller:

The controller layer handles incoming HTTP requests and defines API endpoints. Here’s an example:

I strongly advice you to use ResponseEntity with returning Http status codes. But in this tutorial I don’t want to complicate the writing.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserService userService;

public UserController(UserService userService) {
this.userService = userService;
}

@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
return userService.getUserById(id);
}

@PostMapping
public User createUser(@RequestBody User newUser) {
return userService.createUser(newUser);
}

@PutMapping("/{id}")
public User updateUser(@PathVariable Long id, @RequestBody User updatedUser) {
return userService.updateUser(id, updatedUser);
}

@DeleteMapping("/{id}")
public void deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
}
}

2. Service:

The service layer contains the business logic. It interacts with the repository and performs operations on data. Here’s an example:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {
private final UserRepository userRepository;

public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}

public User getUserById(Long id) {
return userRepository.findById(id).orElse(null);
}

public User createUser(User newUser) {
return userRepository.save(newUser);
}

public User updateUser(Long id, User updatedUser) {
User existingUser = userRepository.findById(id).orElse(null);
if (existingUser != null) {
existingUser.setName(updatedUser.getName());
// Update other properties as needed.
return userRepository.save(existingUser);
}
return null;
}

public void deleteUser(Long id) {
userRepository.deleteById(id);
}
}

3. Model:

The model defines data structures (POJOs — Plain Old Java Objects) used in the application. This Model object is suitable for SQL databases. Here’s an example:

import javax.persistence.*;

@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(name = "name")
private String name;
@Column(name = "email")
private String email;

public Long getId(){ return id;}
public String getName() { return name;}
public String getEmail() { return email;}

public void setId( Long id) { this.id = id;}
public void setName( String name) { this.name = name;}
public void setEmail( String email) { this.email = email;}

}

4. Repository:

The repository handles database operations using Spring Data JPA. You should check how to connect SQL Database to this api but in this tutorial we won’t learn about it. Here’s an example:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
// Custom queries can be added here if needed
}

4. Annotations and Configuration:

Annotations and configuration play a crucial role in a Java Spring project, providing essential information to the Spring framework about how to manage components and control the application’s behavior. Let’s explore why we need them and where they should be placed in the project.

Why We Need Annotations and Configuration:

  1. Component Scanning: Annotations like @RestController, @Service, and @Repository help Spring identify and manage components. Without these annotations, Spring wouldn't know which classes should be treated as controllers, services, or repositories.
  2. Dependency Injection: Annotations like @Autowired are used for dependency injection. They tell Spring where to inject instances of other components, ensuring that classes can collaborate seamlessly.
  3. Custom Configuration: Configuration classes allow you to customize the behavior of your Spring application. You can define properties, enable features like security or database access, and set up third-party integrations.
  4. Simplifying Development: Annotations and configuration eliminate a lot of boilerplate code and XML configuration that was required in older versions of Spring. They make development more concise and easier to read.

5. Documentation:

To document your API, you can use tools like Swagger. Here’s an example configuration:

import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.controller"))
.paths(PathSelectors.any())
.build();
}
}

This configuration enables Swagger for API documentation and specifies the package to scan for controllers.

Application Properties: Configuration properties, such as database connection details or application-specific settings, should be defined in application.properties or application.yml files. These files should be placed in the project's resources directory.

6. So What Are Endpoints and How We Check Our Api:

Endpoints in the context of web development and APIs are specific URLs (Uniform Resource Locators) or URI (Uniform Resource Identifiers) that define the paths or addresses through which clients can interact with a web service, application, or API. These endpoints serve as entry points for making requests to access or manipulate resources on a server. Here’s a more detailed explanation of endpoints:

1. Resource Representation:

Endpoints are associated with specific resources or data entities that an application exposes or manages. These resources can be objects, data, or services that clients want to interact with. For example, in a RESTful API for a blog application, you might have endpoints for creating, retrieving, updating, and deleting blog posts. Each of these endpoints corresponds to a specific resource — a blog post.

2. HTTP Methods:

Endpoints are typically paired with HTTP methods (also known as HTTP verbs) to define the type of operation or action to be performed on the associated resource. Common HTTP methods include:

  • GET: Used to retrieve data from the server. For example, a GET request to /api/posts could fetch a list of all blog posts.
  • POST: Used to create a new resource on the server. A POST request to /api/posts could create a new blog post.
  • PUT: Used to update an existing resource or create a resource if it doesn’t exist. A PUT request to /api/posts/1 could update the content of the first blog post.
  • DELETE: Used to delete a resource. A DELETE request to /api/posts/1 could delete the first blog post.

3. Examples:

Here are a few examples of endpoints:

  • GET /api/posts: Retrieves a list of all blog posts.
  • POST /api/posts: Creates a new blog post.
  • GET /api/posts/1: Retrieves the details of the first blog post.
  • PUT /api/posts/1: Updates the content of the first blog post.
  • DELETE /api/posts/1: Deletes the first blog post.

You can check your api with Postman program by using above examples. (Of course you have to put http://localhost:<portoftheapi>/ at the beginning)

This project structure provides a well-organized foundation for building RESTful APIs with Java Spring. The controller defines endpoints, the service handles business logic, the model represents data, and the repository manages database interactions. Annotations and configuration settings make it all work together seamlessly.

7. AUTHOR NOTES:

  1. We could have opted for the convenience of using @Autowired to inject our repository into our service and our service into the controller. However, initializing them within constructors is a more efficient approach.
  2. You might still be wondering why we need APIs. Allow me to clarify. Imagine a front end developer who has brilliantly designed a website with stunning visuals, buttons, and interactive elements. However, for the website to be truly functional, it must interact with a database or some data source. This is where an API comes into play. The front end developer needs a secure and reliable way to fetch data from or make changes to the data source. This is precisely what an API provides — a safe and controlled environment for data retrieval and manipulation. It acts as the bridge between the beautiful front end and the powerful data resources, ensuring that the website functions seamlessly.
  3. I strongly recommend taking the time to familiarize yourself with the Java programming language, as well as gaining a foundational understanding of key internet protocols and basic concepts, such as what a URL (Uniform Resource Locator) is. Know how to handle exceptions gracefully in your API and return appropriate error responses.
  4. This is a beginner guide so always learn more about Creating Restful Api with Java Spring.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Delirium
Delirium

Written by Delirium

0 Followers

twitter: @suddenconfused

No responses yet

Write a response