0% found this document useful (0 votes)
2 views57 pages

Spring REST API Course Implementation Guide

The document provides an introduction to implementing REST APIs using Java Spring, covering key topics such as creating a Spring project, data models, repositories, services, and controllers. It emphasizes the architecture of a web application and the steps to handle various HTTP requests for retrieving, sending, updating, and removing data. Additionally, it discusses how to adapt the API for non-browser clients and the importance of returning appropriate HTTP responses.

Uploaded by

mraj850288
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views57 pages

Spring REST API Course Implementation Guide

The document provides an introduction to implementing REST APIs using Java Spring, covering key topics such as creating a Spring project, data models, repositories, services, and controllers. It emphasizes the architecture of a web application and the steps to handle various HTTP requests for retrieving, sending, updating, and removing data. Additionally, it discusses how to adapt the API for non-browser clients and the importance of returning appropriate HTTP responses.

Uploaded by

mraj850288
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

JAVA SPRING

INTRODUCTION TO SPRING REST API


issntt@[Link]

1
© National University of Singapore. All Rights Reserved.
Topics

• Why REST Services?


• Implement REST Services
• Retrieve data (list) from servers
• Retrieve data (single entity) from servers
• Send data to servers
• Update data on servers
• Remove data from servers

© National University of Singapore. All Rights Reserved. 2


Problem
Develop a web app that displays a list of courses

© National University of Singapore. All Rights Reserved. 3


Our Architecture
We can develop a web app using MVC and Layered
Architecture

Repositories
Controllers

Services
DB

© National University of Singapore. All Rights Reserved. 4


Implement the App

1. Create a new Java Spring project


2. Create Data Models and JPA Mapping
3. Create Repositories
4. Create Services
5. Create Controllers
6. Create Views
7. Configure to use H2 Database and Hibernate
8. Initialize some data
9. Test

© National University of Singapore. All Rights Reserved. 5


1. Create a new Spring Project
Select Spring Web, Spring Data JPA, H2 Database and
Spring Boot Dev Tools

© National University of Singapore. All Rights Reserved. 6


2. Create Data Models and JPA
Mapping
Create class Course data model and map it

@Entity
@Table(name = "courses")
public class Course {
@Id
@GeneratedValue(strategy = [Link])
private int id;
private String code;
private String name;
private String description;

public Course() {
}

public Course(String code, String name, String description) {


[Link] = code;
[Link] = name;
[Link] = description;
}
// Setters, getters, toString()...
}
© National University of Singapore. All Rights Reserved. 7
3. Create Repositories
Create a respective Repository for Course, of which ID type is
Integer

import [Link];

import [Link];

public interface CourseRepository extends


JpaRepository<Course, Integer>{

© National University of Singapore. All Rights Reserved. 8


4. Create Services
Create a respective service interface that supports listing
Courses

public interface CourseService {


List<Course> findAllCourses();
}

© National University of Singapore. All Rights Reserved. 9


4. Create Services
And provide the respective implementation

@Service
@Transactional (readOnly = true)
public class CourseServiceImpl implements CourseService {
@Resource
private CourseRepository courseRepository;

@Override
public List<Course> findAllCourses() {
return [Link]();
}


}

In a nutshell, without attribute name, @Resource and @Autowired are basically the same
(match-by-type) [Link]

© National University of Singapore. All Rights Reserved. 10


5. Create Controllers
Create a Controller and the respective controller method,
which retrieves the course list and sends it to the view

@Controller
@RequestMapping("courses")
public class CourseController {
@Autowired
private CourseService courseService;

@GetMapping(value = "/list")
public String listCourses(Model model) {
[Link](
"courses", [Link]());
return "courses";
}
}

© National University of Singapore. All Rights Reserved. 11


6. Create the respective Views
The view, using Thymeleaf, loops through each of the courses
and displays its details
<!DOCTYPE html>
<html xmlns:th="[Link]
<head>…</head>
<body>
<h2>Course Listing</h2>
<table th:if="${not #[Link](courses)}">
<tr>
<th>ID</th>
<th>Code</th>
<th>Name</th>
<th>Description</th>
</tr>
<tr th:each="course:${courses}">
<td th:text=${[Link]}>Course ID</td>
<td th:text=${[Link]}>Course Code</td>
<td th:text=${[Link]}>Course Name</td>
<td th:text=${[Link]}>Course Description</td>
</tr>
</table>
</body>
</html>
© National University of Singapore. All Rights Reserved. 12
6. Configure app database
Add more configuration for H2 database and Hibernate
[Link]=jdbc:h2:mem:testdb
[Link]=[Link]
[Link]=sa
[Link]=password
[Link]-platform=[Link].H2Dialect
[Link]=true

[Link]-auto=create

[Link]-sql=true
[Link].format_sql=true

[Link]

© National University of Singapore. All Rights Reserved. 13


7. Initialize some data
Use CommandLineRunner (or [Link] and [Link]) to populate
some course data so that we can use for testing
@SpringBootApplication
public class FullStackMyCoursesServerApplication {

@Bean
CommandLineRunner loadData(CourseRepository courseRepository) {
return (args) -> {
// Add a few courses
Course course1 = new Course();
[Link]("FOPCS");
[Link]("Fundamentals of Programming in C#");
[Link]("FOPCS description");
[Link](course1);

Course course2 = new Course();


[Link]("OOPCS");
[Link]("Object Oriented Programing");
[Link]("OOPCS description");
[Link](course2);
};
}
}

© National University of Singapore. All Rights Reserved. 14


8. Test
Run the Spring App

© National University of Singapore. All Rights Reserved. 15


8. Test
Open a Browser and type the respective URL to list
courses

© National University of Singapore. All Rights Reserved. 16


Problem

What if the clients are


NOT Browsers?
© National University of Singapore. All Rights Reserved. 17
Problem

Android Native
App

Repositories
Controllers

Services
DB

iOS Native App

MacOS Terminal

What if the clients are


NOT Browsers?
© National University of Singapore. All Rights Reserved. 18
Question
Compared to Web
Browsers, for these types HTTP Request

of clients above, what


HTTP Response
should be different in
Android
the HTTP Native
Server
App
Responses?
A. Data
B. UI
C. Both data & UI

© National University of Singapore. All Rights Reserved. 19


Topics

• Why REST Services?


• Implement REST Services
• Retrieve data (list) from servers
• Retrieve data (single entity) from servers
• Send data to servers
• Update data on servers
• Remove data from servers

© National University of Singapore. All Rights Reserved. 20


REST Services (aka REST API)

For non-browsers, the [


{
HTTP responses should "id": 1,
"code": "FOPCS",
not include HTML, but "name": "Fundamentals of
instead Programming in C#",
"description": "FOPCS
• only include data, and description"
},
• in some form that is easy {
for machines to parse and "id": 2,
generate "code": "OOPCS",
"name": "Object Oriented
• e.g., XML, JSON Programing",
"description": "OOPCS
description"
}
]

An example of JSON data

Working with JSON [Link]


US/docs/Learn/JavaScript/Objects/JSON
© National University of Singapore. All Rights Reserved. 21
Topics

• Why REST Services?


• Implement REST Services
• Retrieve data (list) from servers
• Retrieve data (single entity) from servers
• Send data to servers
• Update data on servers
• Remove data from servers

© National University of Singapore. All Rights Reserved. 22


Implement REST Services

Which step(s) should be changed?


1. Create a new Java Spring project
2. Create Data Models and JPA Mapping
3. Create Repositories
4. Create Services
5. Create Controllers
6. Create Views
7. Configure to use H2 Database and Hibernate
8. Initialize some data
9. Test

Note: in this lecture, I show you one way to implement REST Services. It’s NOT the only way.
© National University of Singapore. All Rights Reserved. 23
Implement Controllers
Annotate controllers with @RestController, which bypasses the
model-and-view, and writes data directly to the response body

@RestController
@RequestMapping("/api")
public class CourseController {
@Autowired
private CourseService courseService;

@GetMapping("/courses")
public List<Course> getAllCourses() {
return
[Link]();
}
}

With @RestController, we can understand that there is an implicit


view converting the return entity to JSON
© National University of Singapore. All Rights Reserved. 24
Implement Controllers
The @RequestMapping and @GetMapping annotations determine
the routing

@RestController
@RequestMapping("/api")
public class CourseController {
@Autowired
private CourseService courseService;

@GetMapping("/courses")
public List<Course> getAllCourses() {
return [Link]();
}
}

© National University of Singapore. All Rights Reserved. 25


Implement Controllers
FYI
If APIs are to be consumed by JavaScript-based
frameworks such as Angular or ReactJS, annotate Controllers
with @CrossOrigin

@CrossOrigin
@RestController
@RequestMapping("/api")
public class CourseController {
@Autowired
private CourseService courseService;

@GetMapping("/courses")
public List<Course> getAllCourses() {
return [Link]();
}
}

Reading more about CORS: [Link]


© National University of Singapore. All Rights Reserved. 26
Test
We can use any clients to test. For example, use the curl
Windows command-line utility

© National University of Singapore. All Rights Reserved. 27


Test
Or Postman

[Link]
© National University of Singapore. All Rights Reserved. 28
Next

Instead of retrieving
the whole list of
Courses, can we
fetch only a
single Course,
given its ID? Image by truthseeker08 from Pixabay

© National University of Singapore. All Rights Reserved. 29


Topics

• Why REST Services?


• Implement REST Services
• Retrieve data (list) from servers
• Retrieve data (single entity) from servers
• Send data to servers
• Update data on servers
• Remove data from servers

© National University of Singapore. All Rights Reserved. 30


An attempt
We may apply the same principle. In the controller method, we
return the Course object
@CrossOrigin
@RestController
@RequestMapping("/api")
public class CourseController {
@Autowired
private CourseService courseService;

@GetMapping("/courses/{id}")
public Course getCourseById(int id) {
Optional<Course> optCourse = [Link](id);

if ([Link]()) {
return [Link]();
} else {
return null;
}
}

}

[Link]
© National University of Singapore. All Rights Reserved. 31
Question

What is the HTTP


Response for a not-
found entity? For
example, GET
/api/courses/-1

Image by Johnnie Shannon from Pixabay

© National University of Singapore. All Rights Reserved. 32


An attempt
However, the HTTP Response for not-found entities are
unclear, e.g., response of GET /api/courses/-1 is
HTTP/1.1 200 OK - Status code is 200, not 404
Vary: Origin
Vary: Access-Control-Request-Method - Status code is 200 but body
Vary: Access-Control-Request-Headers is empty
Content-Length: 0
Date: Mon, 14 Aug 2023 07:01:06 GMT
Keep-Alive: timeout=60 How can we send status
Connection: keep-alive code 404 for not-found
entities?

© National University of Singapore. All Rights Reserved. 33


Retrieve a Single Entity
Instead, wrap the object in a ResponseEntity, which represents a
HTTP Response with 1. a status code (compulsory) and 2. an
entity (optional)
@GetMapping("/courses/{id}")
public ResponseEntity<Course> getCourseById(
@PathVariable("id") Integer id) {
Optional<Course> optCourse = [Link](id);

if ([Link]()) {
Course course = [Link]();
return new
ResponseEntity<Course>(course, [Link]);
} else {
return new
ResponseEntity<Course>(HttpStatus.NOT_FOUND);
}
}

[Link]
© National University of Singapore. All Rights Reserved. 34
Test
Like other GET requests, we can use Browsers or
Postman to test

© National University of Singapore. All Rights Reserved. 35


Next

Can we send data


from clients to add
to servers?

Image by truthseeker08 from Pixabay

© National University of Singapore. All Rights Reserved. 36


Topics

• Why REST Services?


• Implement REST Services
• Retrieve data (list) from servers
• Retrieve data (single entity) from servers
• Send data to servers
• Update data on servers
• Remove data from servers

© National University of Singapore. All Rights Reserved. 37


Send Data to Servers
To create new data, we should handle HTTP Post Requests

@PostMapping("/courses")
public ResponseEntity<Course> createCourse(@RequestBody Course inCourse)
{
try {
Course retCourse = [Link](inCourse);

return new ResponseEntity<Course>(retCourse, [Link]);


} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.EXPECTATION_FAILED);
}
}

POST /api/courses HTTP/1.1


Content-Type: application/json

{
"code": "[Link]",
"name": "[Link] MVC Programming",
"description": "Understanding and develop web app using [Link] MVC"
}

© National University of Singapore. All Rights Reserved. 38


Send Data to Servers
The data sent from the client will be bound to the method
parameters, using @RequestBody
@PostMapping("/courses")
public ResponseEntity<Course>
createCourse(@RequestBody Course inCourse) {
try {
Course retCourse = [Link](inCourse);

return new ResponseEntity<Course>(retCourse, [Link]);


} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.EXPECTATION_FAILED);
}
}

POST /api/courses HTTP/1.1


Content-Type: application/json

{
"code": "[Link]",
"name": "[Link] MVC Programming",
"description": "Understanding and develop web app using [Link] MVC"
}
© National University of Singapore. All Rights Reserved. 39
Send Data to Servers
Like previously, we can use ResponseEntity to put the entity
and the status code into the response
@PostMapping("/courses")
public ResponseEntity<Course>
createCourse(@RequestBody Course inCourse) {
try {
Course retCourse = [Link](inCourse);

return new ResponseEntity<Course>(


retCourse, [Link]);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.EXPECTATION_FAILED);
}
}

HTTP/1.1 201 Created Because the entity


… information comes from
the client itself, do the
{"id":3,"code":"[Link]","name":"[Link] MVC
Programming","description":"Understanding and server need to send the
develop web app using [Link] MVC"} entity back in the response?
© National University of Singapore. All Rights Reserved. 40
Test
One way is to use Postman, adding the data to the request
body in JSON form
7
1 2

3
4 5

© National University of Singapore. All Rights Reserved. 41


Next

Can we update
existing
entities on
server?

Image by truthseeker08 from Pixabay

© National University of Singapore. All Rights Reserved. 42


Topics

• Why REST Services?


• Implement REST Services
• Retrieve data (list) from servers
• Retrieve data (single entity) from servers
• Send data to servers
• Update data on servers
• Remove data from servers

© National University of Singapore. All Rights Reserved. 43


Update Data on Servers
To update data, we should handle HTTP Put Requests

@PutMapping("/courses/{id}")
public ResponseEntity<Course> editCourse(
@PathVariable("id") int id, @RequestBody Course inCourse) {
Optional<Course> optCourse = [Link](id);

if ([Link]()) {
Course course = [Link]();

[Link]([Link]());
[Link]([Link]());
[Link]([Link]());

Course updatedCourse = [Link](course);

return new ResponseEntity<Course>(updatedCourse, [Link]);


} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}

© National University of Singapore. All Rights Reserved. 44


Update Data on Servers
Usually, two parameters will be bound. The first one is the ID,
used to find the respective entity to be updated

@PutMapping("/courses/{id}")
public ResponseEntity<Course> editCourse(
@PathVariable("id") int id,
@RequestBody Course inCourse) {
Optional<Course> optCourse = [Link](id);

if ([Link]()) {
Course course = [Link]();

[Link]([Link]());
[Link]([Link]());
[Link]([Link]());

Course updatedCourse = [Link](course);

return new ResponseEntity<Course>(updatedCourse, [Link]);


} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
© National University of Singapore. All Rights Reserved. 45
Update Data on Servers
The second bound parameter includes the new information
used to update the entity
@PutMapping("/courses/{id}")
public ResponseEntity<Course> editCourse(
@PathVariable("id") int id,
@RequestBody Course inCourse) {
Optional<Course> optCourse = [Link](id);

if ([Link]()) {
Course course = [Link]();

[Link]([Link]());
[Link]([Link]());
[Link]([Link]());

Course updatedCourse = [Link](course);

return new ResponseEntity<Course>(updatedCourse, [Link]);


} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
© National University of Singapore. All Rights Reserved. 46
Update Data on Servers
In the response, inform the client if the updating is
successful
@PutMapping("/courses/{id}")
public ResponseEntity<Course> editCourse(
@PathVariable("id") int id, @RequestBody Course inCourse) {
Optional<Course> optCourse = [Link](id);

if ([Link]()) {
Course course = [Link]();

[Link]([Link]());
[Link]([Link]());
[Link]([Link]());

Course updatedCourse = [Link](course);

return new ResponseEntity<Course>(


updatedCourse, [Link]);
} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
© National University of Singapore. All Rights Reserved. 47
Test
One way is to use Postman, adding the data to the
request body in JSON form

7
1 2

3
4 5

© National University of Singapore. All Rights Reserved. 48


Next

Sometimes data
simply isn’t needed
anymore. Can we
remove
entities from
servers? Image by truthseeker08 from Pixabay

© National University of Singapore. All Rights Reserved. 49


Topics

• Why REST Services?


• Implement REST Services
• Retrieve data (list) from servers
• Retrieve data (single entity) from servers
• Send data to servers
• Update data on servers
• Remove data from servers

© National University of Singapore. All Rights Reserved. 50


Delete Data from Servers
To remove data, we should handle HTTP Delete Requests

@DeleteMapping("/courses/{id}")
public ResponseEntity<HttpStatus> deleteCourse(
@PathVariable("id") int id) {
try {
[Link](id);
return new
ResponseEntity<HttpStatus>(HttpStatus.NO_CONTENT);
} catch (Exception e) {
return new
ResponseEntity<HttpStatus>(HttpStatus.EXPECTATION_FAILED);
}
}

© National University of Singapore. All Rights Reserved. 51


Delete Data from Servers
In this example, the ID from URL Path will be used to
remove the course
@DeleteMapping("/courses/{id}")
public ResponseEntity<HttpStatus> deleteCourse(
@PathVariable("id") int id) {
try {
[Link](id);
return new
ResponseEntity<HttpStatus>(HttpStatus.NO_CONTENT);
} catch (Exception e) {
return new
ResponseEntity<HttpStatus>(HttpStatus.EXPECTATION_FAILED);
}
}

© National University of Singapore. All Rights Reserved. 52


Delete Data from Servers
In the response, inform the client if the operation is
successful
@DeleteMapping("/courses/{id}")
public ResponseEntity<HttpStatus> deleteCourse(
@PathVariable("id") int id) {
try {
[Link](id);
return new
ResponseEntity<HttpStatus>(HttpStatus.NO_CONTENT);
} catch (Exception e) {
return new
ResponseEntity<HttpStatus>(
HttpStatus.EXPECTATION_FAILED);
}
}

Do we need to send
the Response Body?
© National University of Singapore. All Rights Reserved. 53
Test
One way is to use Postman, no body is needed
1 2 3

© National University of Singapore. All Rights Reserved. 54


Summary
Annotation HTTP Method (Verb) Typical use

@GetMapping HTTP GET requests Retrieve resource data

@PostMapping HTTP POST requests Create a resource

@PutMapping HTTP PUT requests Update a resource

@DeleteMapping HTTP DELETE requests Delete a resource

@RequestMapping General-purpose request


handling; need to specify
HTTP method in the
method attribute

© National University of Singapore. All Rights Reserved. 55


Summary

• REST APIs can be created by Spring MVC using the same model
as browser-targeted controllers
• Controller methods should be annotated with @RestController
to bypass the model and view, and write data directly to the
response body
• @RestControllers share the same routing and model binding
mechanisms with browser-targeted controllers
• Class ResponseEntity represents a response with an entity and
a HTTP status code
• Different HTTP Methods, e.g., Get, Post, Put, Delete, are used
for different purposes

© National University of Singapore. All Rights Reserved. 56


Readings

• Spring in Action 6ed, Chapter 7 – Creating


REST Services, section 7.1, by Craig Walls

© National University of Singapore. All Rights Reserved. 57

You might also like