REST API Using Spring Boot - Level 1
Tags: java, spring, tutorial, api
Published: 2023-02-12 13:26:31

In this tutorial, we are going to create a simple REST API using Spring Boot for an imaginary user management application. Our target is to get familiar with the code structure and the annotations. We will create HTTP endpoints and for now return static values. Considering an imaginary user management application, we will be implementing the following endpoints.

**Method Type: `GET`**
	1. `/users`: returns all users
	2. `/users/{userId}`: returns the user with the matching user ID
**Method Type: `POST`**
	1. `/users`: create new user
**Method Type: `PATCH`**
	1. `/users/{userId}`: update user details with the matching user ID
**Method Type: `DELETE`**
	1. `/users/{userId}`: delete user with the matching user ID

## Project Setup
Generate a spring project from [Spring Initializer](https://start.spring.io/). Add `Spring Web` as the dependency. Before clicking generate the values should be like:

![Spring REST API setup](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1waskm90udebearer7ls.png)
Key things to note:
1. Choose project type as **Maven**
2. Don't choose any snapshot version for Spring Boot i.e. don't choose any version with `(SNAPSHOT)` written beside it.
3. Add **Spring Web** as dependency.

For this tutorial, we will be creating all the files in the package that is created by default.

## Initializing REST API
Spring follows **MVC**(Model-View-Controller) pattern where the aim of the controller is to handle requests. The controller determines what information is to be sent to the user when the user makes a request. So, to handle the requests for our REST application, we need our own controller.

Now, Spring understands code using annotations and to let it know that we are creating a REST API controller, we use the annotation `@RestController` which tells spring that this code will be handling the HTTP requests.
```java
@RestController  
public class MyController {  
	
}
```
With the controller defined, if we run our spring application now and visit the default url for spring application i.e. `localhost:8080` in the browser then we can see the following output:

![White Label Error Spring](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o1ti8id4cyelkeyetimj.png)
## HTTP Annotations Overview
This error is shown because we haven't defined any endpoints yet. Whenever we are visiting `http://localhost:8080`, we are essentially making a `GET` request on the URL but since we have no endpoint defined for it, Spring shows the **White Label Error**. But before we jump to the endpoints, let's learn the annotations first.

Spring provides annotations for all types of HTTP requests. They are:
1. GET: `@GetMapping("/path")`
2. POST: `@PostMapping("/path")`
3. PATCH: `@PatchMapping("/path")`
4. PUT: `@PutMapping("/path")`
5. DELETE: `@DeleteMapping("/path")`

There are 2 other annotations that we will be using are:
`@RequestBody`: to access data provided in the HTTP request body
`@PathVariable`: to access any variable provided in the URL. Suppose we need to get a user record matching a specific ID, then we can pass the user ID in the URL like `/path/{userId}` and can access it using `@PathVariable`. We will see the implementations for all the annotations as we follow along.

## Define HTTP Methods For REST API
Currently, when we visit `http://localhost:8080` in the browser, we are getting the default message i.e. **Whitelabel Error Page**. Let's change this. We want to show our own message here.

To do this, we need to identify the type of HTTP request that is being used and how to define that HTTP request. So, by default, any URL we visit, we are making a `GET` request to the server. So, to show the custom message in the Home Page, we need to define a `GET` endpoint but for which URL? Since, this is the home page, there is no extra path, so its essentially the default path which is `http://localhost:8080`. With that being said, let's define the HTTP method.
```java
@RestController  
public class MyController {  
    @GetMapping("/")  
    public String home() {  
        return "Welcome to REST API tutorial using Spring Boot";  
    }  
}
```
Now, if we restart the application and visit `http://localhost:8080` again, then we can see the text `"Welcome to REST API tutorial using Spring Boot"`. Now that we have got our application running, let's create the HTTP endpoints for our application. For now, we will return simple text messages as outputs from the REST API. 

### GET All Users
Our first endpoint is `/users`. We want to get all the user data via this endpoint. Essentially, we are making a GET request on `/users`. Its implementation is:
```java
@GetMapping("/users")  
public String getAllUsers() {  
    return "All users";  
}
```

### GET One User 
Now we want to provide a User ID and get the user whose ID matches the provided User ID. Here, the user ID will be passed through the query as `/users/{userID}` and using `@PathVariable`, we will be able to access it. Upon getting the User ID, we will return a text as `Found user with user ID: {userID}`. The coding implementation for the same is:
```java
@GetMapping("/users/{userId}")
public String getUser(@PathVariable long userId) {  
    return "Found user with user ID: " + userId;  
}
```

### Create New User
For creating a new user, we need to send data to the REST API, so that it can create the user in the database. So, we are doing a `POST` request to the REST API on the URL `/users`.
```java
@PostMapping("/users")  
public String createUser() {  
    return "New user created";  
}
```

### Update User
To update an user, we need 2 things: some unique identifier(e.g. User ID) through which we can identify the user records that needs to be updated and the updated data. Currently, we won't be sending any updated data. We will simply focus on the functions and annotations. So, for updating, we can use the `PATCH` or the `PUT` HTTP methods.

>If you are wondering why do we use `PATCH` and `PUT` for updating data and not `POST` then this [QnA in StackOverflow]([http - What is the difference between PUT, POST and PATCH? - Stack Overflow](https://stackoverflow.com/questions/31089221/what-is-the-difference-between-put-post-and-patch#:~:text=POST%20is%20always%20for%20creating,always%20for%20updating%20a%20resource)) is the best. It defines the differences between `POST`, `PATCH` and `PUT` in detail.

So, back to our updating user, our implementation will be:
```java
@PatchMapping("/users/{userId}")  
public String updateUser(@PathVariable long userId) {  
    return "User with user ID: " + userId + " updated";  
}
```

### Delete User
This is almost similar to Update User. We need to pass a unique identifier in the query and if the idenfier matches a user, then delete the user. For now, we will be sending a text as the response.
```java
@DeleteMapping("/users/{userId}")  
public String deleteUser(@PathVariable long userId) {  
    return "User: " + userId + " deleted";  
}
```

Combining all of these, our controller file i.e. `MyController.java` looks like:
```java
@RestController  
public class MyController {  
    @GetMapping("/")  
    public String home() {  
        return "Welcome to REST API tutorial using Spring Boot";  
    }  
  
    @GetMapping("/users")  
	public String getAllUsers() {  
	    return "All users";  
	}  
  
    @GetMapping("/users/{userId}")
	public String getUser(@PathVariable long userId) {  
	    return "Found user with user ID: " + userId;  
	} 
  
    @PostMapping("/users")  
	public String createUser() {  
	    return "New user created";  
	}  
  
	@PatchMapping("/users/{userId}")  
	public String updateUser(@PathVariable long userId) {  
	    return "User with user ID: " + userId + " updated";  
	}  
      
	@DeleteMapping("/users/{userId}")  
	public String deleteUser(@PathVariable long userId) {  
	    return "User: " + userId + " deleted";  
	}
}
```
With the endpoints defined, we have our REST API using Spring Boot ready. Run the Spring Boot application and, our REST API is ready to run on `http://localhost:8080`. Use [Postman](https://www.postman.com/) or any other method to test the various endpoints.

## Summary
To summarize our application, we have:
1. created a Spring Boot project with **Spring Web** as the dependency.
2. created a Java class called `MyController` and defined it as controller using `@RestController`
3. implemented the HTTP methods using: `@GetMapping`, `@PostMapping`, `@PatchMapping`, `@PutMapping` and `@DeleteMapping`
4. learnt how to get a variable from URL using `@PathVariable`

Here, we have got an overview of how to create a REST API using Spring Boot and the various annotations required for it. But to make the API more realistic, we need to be able to store and return actual data as response. In [REST API Using Spring Boot - Level 2](https://dev.to/souvikdas/rest-api-using-spring-boot-level-2-4kh3), I have shown how to use a Java class as a storage to make the API realistic.