spring boot rest example

Summary: This article will help you create a simple REST service with Spring Boot.

 

you will learn

 

  • What is a REST service?
  • How to create a Rest service application using Spring Initializr Bootstrap?
  • How do I create a fetch REST service to retrieve the courses a student is enrolled in?
  • How do I create a Post REST service for students enrolling in courses?
  • How to use postman to perform rest service?

 

The rest service used in this tutorial

 

In this tutorial, we will create three services with the appropriate URI and HTTP method:

 

@GetMapping("/students/{studentId}/courses"): You can use the request method Get and the example uri /students/Student1/courses to query the courses a particular student has registered for.

 

@GetMapping("/students/{studentId}/courses/{courseId}"): You can get a specific course for a specific student using the request method Get and the example uri /students/Student1/courses/Course1.

 

@PostMapping("/students/{studentId}/courses") : You can register a student for a course by sending a POST request to the UURI /students/Student1/courses

 

tools you will need

 

  • Maven 3.0+ is your build tool
  • your favorite IDE. We use Eclipse.
  • JDK 1.8+

 

Complete spring boot rest Maven project code example

 

Our Github repository contains all code samples - 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 satisfies these conditions is called a RESTful service.

 

Five important conditions for RESTful Web Services:

 

  • Client-Server: There should be one service producer and one service consumer.
  • The interface (URL) is uniform and exposes resources.
  • The service is stateless.
  • Serving results should be cacheable. For example HTTP caching.
  • Services should adopt a layered architecture. The client should not connect directly to the server - it may get information from the middle tier - cache.

 

Richardson Maturity Model

 

The Richardson Maturity Model is used to identify the maturity level of Restful Web Services. Here are the different levels and features:

 

  • Level 0: Expose SOAP web services in a REST style. The exposed operations use REST services (http://server/getPosts, http://server/deletePosts, http://server/doThis, http://server/doThat, etc.).

  • Level 1: Expose resources with correct URIs (using nouns). 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. To create an account, 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). Not only can you understand the requested information, but you can also understand the next possible action that the service consumer 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 most recent comments, and how to retrieve a list of his friends.

 

Use the appropriate request method

 

Always use the HTTP method. Best practices for each HTTP method are described below:

 

  • GET: Nothing should be updated. Should be idempotent (calling the same result multiple times). Possible return codes 200 (OK) + 404 (NOT FOUND) + 400 (BAD REQUEST)

  • POST: A new resource should be created. Ideally return JSON and link to the newly created resource. Use the same return code whenever possible. Also: return code 201 (create) is possible.

  • PUT: Update known resources. For example: update customer details. Possible return codes: 200 (OK)

  • DELETE: Used to delete resources.

 

Project structure

 

The following screenshot shows the structure of the project we will create.

 

56b51302f24e4fec889463edaef7ce96.png

 

Some details:

 

  • StudentController.java - rest controller provides all three service methods discussed above.
  • Course.java, Student.java, StudentService.java - Business logic of the application. StudentService provides some methods that we consume from Rest controllers.
  • StudentControllerIT.java - Integration test for rest service.
  • StudentControllerTest.java - Unit tests for the test service.
  • StudentServicesApplication.java - Launcher for Spring Boot applications. To run the application, simply start the file as a Java application.
  • pom.xml - contains all dependencies needed to build this project. We will use Spring Boot Starter Web.

 

Bootstrap REST service creation with Spring Initializr

 

Creating a REST service with Spring Initializr is very easy and a piece of cake. We will use Spring Web MVC as our web tier framework.

 

Spring Initializr http://start.spring.io/ is a great tool for bootstrapping Spring Boot projects.

 

74b1f1e74b3b47f6b2a1bc44aeda9a25.png

 

As shown in the image above, 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
      • Web
      • Actuator
      • DevTools
  • Click Generate Project.
  • Import the project into Eclipse. File -> Import -> Existing Maven Project.
  • If you want to know all the files of this project, you can read on.

 

Application business layer implementation

 

All applications require data. Instead of interacting with a real database, we will use an in-memory data store like an ArrayList.

 

A student can take multiple courses. Courses have an ID, name, description and a list of steps that need to be completed to complete the course. The student has an ID, name, description and a list of courses he/she is currently enrolled in. StudentService provides the following public methods

 

  • public List retrieveAllStudents() - retrieves details of all students
  • public Student retrieveStudent(String studentId) - retrieves specific student details
  • public List retrieveCourses(String studentId) - Retrieves all courses the student is enrolled in
  • public Course retrieveCourse(String studentId, String courseId) - Retrieves details of a specific course a student is enrolled in
  • public Course addCourse(String studentId, Course course) - add a course for an existing student

 

Please refer to the following files, the specific implementation service class StudentService and model classes Course and Student.

 

  • src/main/java/com/in28minutes/springboot/model/Course.java
  • src/main/java/com/in28minutes/springboot/model/Student.java
  • src/main/java/com/in28minutes/springboot/service/StudentService.java

 

Add several GET Rest services

 

Rest service StudentController exposes several get services.

 

  • @Autowired private StudentService studentService : We use Spring Autowiring to automatically inject the student service into the StudentController.
  • @GetMapping("/students/{studentId}/courses"): Publicly obtain services with studentId as a path variable
  • @GetMapping("/students/{studentId}/courses/{courseId}"): A public fetch service to retrieve a student's specific course.
  • @PathVariable String studentId: The value of studentId from the uri will be mapped to this parameter.

 

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;

@RestController
public class StudentController {

	@Autowired
	private 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);
	}

}

 

Execute Get Service Using Postman
We will test the service by making a request to http://localhost:8080/students/Student1/courses/Course1. The response is shown below.

 

{
  "id": "Course1",
  "name": "Spring",
  "description": "10 Steps",
  "steps": [
    "Learn Maven",
    "Import Project",
    "First Example",
    "Second Example"
  ]
}

 

The picture below shows how we do Postman's Get Service - my favorite tool for running rest services.
35bb72fb55374ef38687f72b1f7078e2.png

 

Add POST Rest service

 

When the resource is successfully created, the POST service should return the created status (201).

 

  • @PostMapping("/students/{studentId}/courses"): map URLs for POST requests
  • @RequestBody Course newCourse: Use binding to bind the request body to the course object.
  • ResponseEntity.created(location).build(): Returns the created state. Also returns the location where the resource was created as a response header.

 

	@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();
	}

 

A sample request to perform a POST Rest service
is shown below. It contains all the details of the student's registration for the course.

 

{
  "name": "Microservices",
  "description": "10 Steps",
  "steps": [
    "Learn How to Break Things Up",
    "Automate the hell out of everything",
    "Have fun"
  ]
}

 

The image below shows how we can execute the Post service from Postman - my favorite tool for running rest services. Make sure you go to the Body tab and select raw. Select JSON from the drop-down menu. Copy the above request into the body.

 

The URL we use is http://localhost:8080/students/Student1/courses.

 

096c2dad0bf8496880e051c93319b70f.png

 

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>
			<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;

@RestController
public class StudentController {

	@Autowired
	private 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);
	}
	
	@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;
	}

	@Override
	public String toString() {
		return String.format(
				"Course [id=%s, name=%s, description=%s, steps=%s]", id, name,
				description, steps);
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public 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) {
			if (other.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;
	}

	@Override
	public 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.stereotype.Component;

import com.in28minutes.springboot.model.Course;
import com.in28minutes.springboot.model.Student;

@Component
public class StudentService {

	private static List<Student> students = new ArrayList<>();

	static {
		//Initialize Data
		Course 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 ranga = 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;

@SpringBootApplication
public class StudentServicesApplication {

	public static void main(String[] args) {
		SpringApplication.run(StudentServicesApplication.class, args);
	}
}

 

Author: tom
Source: http://www.3xmq.com/article/1521428370127
Source: The copyright of this article belongs to the author and iteye . Reprints are welcome, but this statement must be retained without the author's consent, and given in an obvious position on the article page Link to the original text, otherwise reserve the right to pursue legal responsibility.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326220847&siteId=291194637