Introduction: This article will help you create a simple REST service using Spring Boot.
You will learn
The rest service used in this tutorial
In this tutorial, we will create three services using the appropriate URI and HTTP methods:
@GetMapping("/students/{studentId}/courses"): You can query courses that a specific student has registered with using the request method Get and the sample uri/students/Student1/courses.
@GetMapping("/students/{studentId}/courses/{courseId}"): You can use the request method Get and sample uri/students/Student1/courses/Course1 to get a specific course for a specific student.
@PostMapping("/students/{studentId}/courses"): You can register a course for students by sending a POST request to UURI /students/Student1/courses
Tools you will need
Complete spring boot rest Maven project code example
Our Github repository contains all code examples - https://github.com/in28minutes/in28minutes.github.io/tree/master/code-zip-files
REST service with unit and integration tests
Website-springbootrestservices-simplerestserviceswithunitandintegrationtests.zip
What is REST?
REST stands for REpresentational State Transfer. REST specifies a set of architectural constraints. Any service that meets these conditions is called a RESTful service.
Five important conditions for RESTful Web Service:
Richardson Maturity Model
The Richardson maturity model is used to identify the maturity level of Restful Web Service. The following are the different levels and characteristics:
Level 0: Expose SOAP Web Services in REST style. The exposed operations use the REST service (http://server/getPosts, http://server/deletePosts, http://server/doThis, http://server/doThat, etc.).
Level 1: Use the correct URI (using noun) to expose the resource. For example: http://server/accounts, http://server/accounts/10. However, the HTTP method is not used.
Level 2: The resource uses the correct URI + HTTP method. For example, to update an account, you need to do a PUT. Create an account and you do a POST. Uri looks like posts/1/comments/5 and accounts/1/friends/1.
Level 3: HATEOAS (Hypermedia as the engine of application state). You can not only understand the requested information, but also the next possible action that service consumers can take. When requesting information about a Facebook user, the REST service can return user details and information on how to get his recent posts, how to get his recent comments, and how to retrieve a list of his friends.
Use the appropriate request method
Always use the HTTP method. The best practices for each HTTP method are as follows:
GET: Nothing should be updated. It should be idempotent (the same result is called multiple times). Possible return code 200 (OK) + 404 (NOT FOUND) + 400 (BAD REQUEST)
POST: New resources should be created. Ideally return JSON and link to newly created resources. Use the same return code whenever possible. Also: Return code 201 (created) is possible.
PUT: Update known resources. For example: Update customer details. Possible return code: 200 (OK)
DELETE: Used to delete resources.
Project structure
The following screenshot shows the structure of the project we will create.
Some details:
Create a REST service using Spring Initializr boot
Creating a REST service with Spring Initializr is a very easy piece of cake. We will use Spring Web MVC as our web layer framework.
Spring Initializr http://start.spring.io/ is a great tool to bootstrap the creation of Spring Boot projects.
As shown in the above figure, the following steps must be performed
Start Spring Initializr and select the following
Select com.in28minutes.springboot as Group
Select student-services as Artifact
Select the following dependencies
Click to generate the project.
Import the project into Eclipse. File -> Import -> Existing Maven Projects.
If you want to know all the files of this project, you can continue reading down.
Application business layer implementation
All applications require data. We will use ArrayList, which is an in-memory data store, rather than interacting with a real database.
A student can take multiple courses. The course has an ID, name, description and a list of steps to complete the course. The student has an ID card, name, description and a list of courses he/she is currently enrolled in. StudentService provides the following public methods
public List retrieveAllStudents() - Retrieve details of all students
public Student retrieveStudent(String studentId) - Retrieve specific student details
public List retrieveCourses(String studentId) - Search all courses students register for
public Course retrieveCourse(String studentId, String courseId) - Retrieve details of a specific course that a student has registered for
public Course addCourse(String studentId, Course course) - Add courses to existing students
Please refer to the following files to implement the service class StudentService and the model class Course and Student.
Add several GET Rest services
Rest service StudentController exposes several get services.
package com.in28minutes.springboot.controller;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RestController;import com.in28minutes.springboot.model.Course;import com.in28minutes.springboot.service.StudentService;@RestControllerpublic class StudentController {@Autowiredprivate StudentService studentService;@GetMapping("/students/{studentId}/courses")public List<Course> retrieveCoursesForStudent(@PathVariable String studentId) {return studentService.retrieveCourses(studentId);}@GetMapping("/students/{studentId}/courses/{courseId}")public Course retrieveDetailsForCourse(@PathVariable String studentId,@PathVariable String courseId) {return studentService.retrieveCourse(studentId, courseId);}}Use Postman to perform a get service
We will initiate a request to http://localhost:8080/students/Student1/courses/Course1 to test the service. The response is as follows.
{ "id": "Course1", "name": "Spring", "description": "10 Steps", "steps": [ "Learn Maven", "Import Project", "First Example", "Second Example" ]}The picture below shows how we execute Postman's Get Service - my favorite tool to run rest service.
Add POST Rest Service
When the resource creation is successful, the POST service should return the created status (201).
@PostMapping("/students/{studentId}/courses")public ResponseEntity<Void> registerStudentForCourse(@PathVariable String studentId, @RequestBody Course newCourse) {Course course = studentService.addCourse(studentId, newCourse);if (course == null)return ResponseEntity.noContent().build();URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(course.getId()).toUri();return ResponseEntity.created(location).build();}Execute POST Rest Service
The sample request is shown below. It contains all the details of students enrolling in the course.
{ "name": "Microservices", "description": "10 Steps", "steps": [ "Learn How to Break Things Up", "Automate the hell out of everything", "Have fun" ]}The following image shows how we execute Post service from Postman - my favorite tool to run rest service. Make sure you go to the Body tab and select raw. Select JSON from the drop-down menu. Copy the above request to the body.
The URL we are using is http://localhost:8080/students/Student1/courses.
Complete code example
pom.xml
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.in28minutes.springboot</groupId><artifactId>student-services</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>student-services</name><description>Demo project for Spring Boot</description><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.4.4.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version></properties><dependencies>< dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></ dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot- starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
src/main/java/com/in28minutes/springboot/controller/StudentController.java
import java.net.URI;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.servlet.support.ServletUriComponentsBuilder;import com.in28minutes.springboot.model.Course;import com.in28minutes.springboot.service.StudentService;@RestControllerpublic class StudentController {@Autowiredprivate StudentService studentService;@GetMapping("/students/{studentId}/courses")public List<Course> retrieveCoursForStudent(@PathVariable String studentId) {return studentService.retrieveCourses(studentId);}@GetMapping("/students/{studentId}/courses/{courseId}")public Course retrieveDetailsForCourse(@PathVariable String studentId,@PathVariable String courseId) {return studentService.retrieveCourse(studentId, courseId);}@PostMapping("/students/{studentId}/courses")public ResponseEntity<Void> registerStudentForCourse(@PathVariable String studentId, @RequestBody Course newCourse) {Course course = studentService.addCourse(studentId, newCourse);if (course == null)return ResponseEntity.noContent().build();URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(course.getId()).toUri();return ResponseEntity.created(location).build();}}src/main/java/com/in28minutes/springboot/model/Course.java
import java.util.List;public class Course {private String id;private String name;private String description;private List<String> steps;// Needed by Caused by: com.fasterxml.jackson.databind.JsonMappingException:// Can not construct instance of com.in28minutes.springboot.model.Course:// no suitable constructor found, can not deserialize from Object value// (missing default constructor or creator, or perhaps need to add/enable// type information?)public Course() {}public Course(String id, String name, String description, List<String> steps) {super();this.id = id;this.name = name;this.description = description;this.steps = steps;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getDescription() {return description;}public String getName() {return name;}public List<String> getSteps() {return steps;}@Overridepublic String toString() {return String.format("Course [id=%s, name=%s, description=%s, steps=%s]", id, name, description, steps);}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((id == null) ? 0 : id.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Course other = (Course) obj;if (id == null)return false;} else if (!id.equals(other.id))return false;return true;}}src/main/java/com/in28minutes/springboot/model/Student.java
package com.in28minutes.springboot.model;import java.util.List;public class Student {private String id;private String name;private String description;private List<Course> courses;public Student(String id, String name, String description,List<Course> courses) {super();this.id = id;this.name = name;this.description = description;this.courses = courses;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public List<Course> getCourses() {return courses;}public void setCourses(List<Course> courses) {this.courses = courses;}@Overridepublic String toString() {return String.format("Student [id=%s, name=%s, description=%s, courses=%s]", id,name, description, courses);}}src/main/java/com/in28minutes/springboot/service/StudentService.java
package com.in28minutes.springboot.service;import java.math.BigInteger;import java.security.SecureRandom;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import org.springframework.steretype.Component;import com.in28minutes.springboot.model.Course;import com.in28minutes.springboot.model.Student;@Componentpublic class StudentService {private static List<Student> students = new ArrayList<>();static {//Initialize DataCourse course1 = new Course("Course1", "Spring", "10 Steps", Arrays.asList("Learn Maven", "Import Project", "First Example","Second Example"));Course course2 = new Course("Course2", "Spring MVC", "10 Examples",Arrays.asList("Learn Maven", "Import Project", "First Example","Second Example"));Course course3 = new Course("Course3", "Spring Boot", "6K Students",Arrays.asList("Learn Maven", "Learn Spring","Learn Spring MVC", "First Example", "Second Example"));Course course4 = new Course("Course4", "Maven","Most popular maven course on internet!", Arrays.asList("Pom.xml", "Build Life Cycle", "Parent POM","Importing into Eclipse"));Student range = new Student("Student1", "Ranga Karanam","Hiker, Programmer and Architect", new ArrayList<>(Arrays.asList(course1, course2, course3, course4)));Student satish = new Student("Student2", "Satish T","Hiker, Programmer and Architect", new ArrayList<>(Arrays.asList(course1, course2, course3, course4)));students.add(ranga);students.add(satish);}public List<Student> retrieveAllStudents() {return students;}public Student retrieveStudent(String studentId) {for (Student student : students) {if (student.getId().equals(studentId)) {return student;}}return null;}public List<Course> retrieveCourses(String studentId) {Student student = retrieveStudent(studentId);if (student == null) {return null;}return student.getCourses();}public Course retrieveCourse(String studentId, String courseId) {Student student = retrieveStudent(studentId);if (student == null) {return null;}for (Course course : student.getCourses()) {if (course.getId().equals(courseId)) {return course;}}return null;}private SecureRandom random = new SecureRandom();public Course addCourse(String studentId, Course course) {Student student = retrieveStudent(studentId);if (student == null) {return null;}String randomId = new BigInteger(130, random).toString(32);course.setId(randomId);student.getCourses().add(course);return course;}}src/main/java/com/in28minutes/springboot/StudentServicesApplication.java
package com.in28minutes.springboot;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class StudentServicesApplication {public static void main(String[] args) {SpringApplication.run(StudentServicesApplication.class, args);}}The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.