From entry to proficiency in RESTful, it is enough to read this article

learning requirements

Good java foundation, familiar with SpringBoot framework, familiar with SpringMVC framework

teaching objectives

Master RESTful interface design

video tutorial

5 hours to take you from getting started to proficient in RESTful interface design

bedding

Let me explain first that this tutorial is not academic, and does not focus on theoretical research and discussion, but only teaches from a practical perspective. Before talking about RESTful, let’s make three foreshadowings: 1> API 2> History of WEB development 3> Separation of front-end and back-end

What is an API

API (Application Programming Interface, application programming interface) is some pre-defined functions , or refers to the agreement of different components of the software system. [1] The purpose is to provide applications and developers the ability to access a set of routines based on a piece of software or hardware without having to access the source code, or understand the details of the inner workings .

Developer A has developed software A, and developer B is developing software B.

One day, developer B wants to use some functions of software A, but he doesn't want to go through the source code and function realization process of software A from the beginning, what should he do?

Developer A thought of a good idea: I packaged the functions you need in software A; if you put this package in software B, you can directly use my method!

Among them, API is the method that developer A said.

Stages of web development

The development of Web development technology can be roughly divided into the following stages

Static Content Phase : In this initial phase, the Web is primarily used by research institutions. The Web consists of large numbers of static HTML documents.

CGI program phase : In this phase, the Web server adds some programming APIs. Applications written through these APIs can provide some dynamically changing content to clients. .

Scripting language stage : In this stage, session-supporting scripting language technologies such as ASP, PHP, JSP, and ColdFusion appear on the server side, and technologies such as Java Applet and JavaScript appear on the browser side. Using these techniques, richer and more dynamic content can be provided.

Thin client application stage : In this stage, an application server independent of the Web server appears on the server side. At the same time, the Web MVC development model appeared, and various Web MVC development frameworks gradually became popular and occupied a dominant position. Web applications developed based on these frameworks are usually thin client applications because they generate all dynamic content on the server side.

RIA application stage : In this stage, a variety of RIA (Rich Internet Application) technologies emerged, which greatly improved the user experience of Web applications. The most widely used RIA technology is DHTML+Ajax. Ajax technology supports dynamic updating of partial content on a page without refreshing the page. At the same time, a large number of Web front-end DHTML development libraries were born, such as Prototype, Dojo, ExtJS, jQuery/jQuery UI and so on.

Mobile Web application stage : In this stage, a large number of Web application development technologies for mobile devices have emerged. In addition to the native development technologies of operating system platforms such as Android, iOS, and Windows Phone, HTML5-based development technologies have also become very popular.

Traditional VS front-end and back-end separation

traditional development model

The front-end writes the static html page to the back-end development, the back-end changes the html into a template, and then uses the template engine to set the template, such as jsp, freemarker and other back-end personnel. If there is a problem with the page during the development process, it should be returned to The front-end is modified, and the front-end is handed over to the back-end until the function is realized.

Problem: Severely coupled front and rear ends

1. When the front-end needs to modify bugs and debug, it is necessary to install a complete set of back-end development tools on the current computer and start the back-end program.

2. Back-end personnel are also required to know front-end languages ​​such as html and js.

3. The front-end page will also embed a lot of back-end code

4. Once the backend is changed to a language, the frontend also needs to be redeveloped

5. Communication costs, debugging costs, front-end and back-end development progress affect each other, thus greatly reducing development efficiency

Separation of front and rear ends

The separation of front and back end is not only a development mode, but also an architectural mode of web applications. In the development stage, the front-end and back-end personnel agree on the data interaction interface, and then they can develop and test in parallel.

After the front-end development is completed, mock tests can be performed independently, and the back-end can also be tested using interface testing tools such as postman. Finally, the function joint debugging test can be carried out.

advantage:

1. The front-end and back-end responsibilities are clear, the back-end focuses on data, and the front-end focuses on vision.

2. There is no need to wait for the end of the other party's development work to improve development efficiency.

3. Can cope with complex and changeable front-end requirements.

4. Enhance code maintainability

RESTful interface design

reason for existence

With the emergence of the web2.0 stage, the client will not be limited to PC browsers, it may be a mobile APP or a small program, which requires the server to provide a unified API interface, and different types of clients are based on the same protocol /Rules can call the API interface and get the expected data.

At this point the core: how to design a set of scientific API interface?

Different developers have different design habits for API interfaces, for example, this may happen

新增员工:
http://localhost/employee/save
http://localhost/employee/add
http://localhost/employee/new
http://localhost/employee/xinzeng
http://localhost/employee/append
http://localhost/employee?cmd=add

而且发送的请求方式以及响应结果也比较可能随意 

Answer: API interface with RESTful style

RESTful style

REST is a rule (style) for designing API interfaces. It is very popular in web projects because of its simplicity, readability, and ease of use. When designing an interface, an application or design that satisfies the constraints and principles of REST is called a RESTful application.

binding rules

Looking back, the traditional web interface (request mapping method) design needs to consider several points.

Take the list of employees as an example.

@Controller
public class EmployeeController {
    @RequestMapping("/employee/list")
    public String list(Model model){
        model.addAttribute("list", employeeService.list())
        return "employee/list";
    }
}

traditional interface design

When designing traditional web interfaces consider:

1> Request path

Generally, the method of seeing the name and knowing the meaning is adopted, such as: /employee/list

2> Request method

Don't care, the @RequestMapping annotation can accept any request method, including: GET POST

3> Request parameters

Not fixed, it depends on the function of the interface, it can be said that it is determined by the demand

4> Request Response

It is not fixed, it depends on the requirements, it can be in Json format or a page template.

RESTful interface design

Take the list of employees as an example.

@Controller
public class EmployeeController {
    @RequestMapping(value = "/employees", method = RequestMethod.GET)
	@ResponseBody
    public List<Employee> list(){
        return employeeService.list();
    }
}

1> Request path

It is no longer a way of knowing the name, but is determined by the resource of the operation. Generally, the plural form of the resource name is used.

For example, the interface operation object (resource) is an employee, and the path can be designed as: /employees

The question is, what are resources?

everything is a resource

In the eyes of RESTful, everything on the Internet is a resource, and each resource has a unique resource locator (URI).

A picture is a resource: https://c-ssl.duitang.com/uploads/item/201810/17/20181017111458_dqioq.jpg

A web page is a resource: Baidu, you will know

A request path is a resource: http://localhost:8080/employee?id=1

Returning to the code, the url http://localhost:8080/employee?id=1 means to query the employee information with id=1 in the database. This employee information is the resource described in restful. Generally, there is not only one resource, just like an employee Not only the data with id=1, most of them are in plural, so the RESTful agreement: for the interface to operate resources, use plural in a unified way.

@RequestMapping("/employees")
public class EmployeeController{

}

Take a look at the following examples:
department resource
http://www.langfeiyes.cn/depts 
zoo resource
https://api.example.com/v1/zoos
animal resource
https://api.example.com/v1/animals
breeder Resource
https://api.example.com/v1/employees

Look at the restful interface written by others Jiguang IM - REST API - Jiguang Documentation

The final vernacular summary: RESTful interface design - the path is generally to operate the plurality of entity objects

2> Request method

The traditional interface design method, using the design path of knowing the name and meaning, can see the operation of the interface on the resource from the path, but the RESTful style interface uses the plural number of resources as the path, so it is impossible to see the operation of the interface on the resource from the path, so what should I do? ?

The RESTful style makes a fuss about the HTTP request method, and agrees:

GET (SELECT): Get a resource (one or more items) from the server.

POST (CREATE): Create a new resource on the server.

PUT (UPDATE): Update the resource on the server (the client provides the complete resource after the change). PUT updates the entire object

PATCH (UPDATE): Update resource on server (client provides changed attributes [patch]). PATCH to update individual attributes

DELETE (DELETE): Deletes a resource from the server.

//learn

HEAD: Obtain the metadata of a resource, such as the hash value or last modification date of a resource; OPTIONS: Obtain the operations that the client can perform on a resource; (obtain the api of the resource (the description of what operations can be performed on the resource))

The traditional path sees the name and the meaning = RESTful path + request method

example

Traditional way:

http://www.langfeiyes.cn/employee/list

http://www.langfeiyes.cn/employee/get?id=1

http://www.langfeiyes.cn/employee/save?name=xx

http://www.langfeiyes.cn/employee/update?id=1&name=xx

http://www.langfeiyes.cn/employee/delete?id=1

RESTful way:

http://www.langfeiyes.cn/employees 
Add: POST 
Update: PUT 
Delete: DELETE 
Query: GET

GET /zoos: List all zoos 
POST /zoos: Create a new zoo 
GET /zoos/{id}: Get the information of a specified zoo 
PUT /zoos/{id}: Update the information of a specified zoo (provide the information of the zoo All information) 
PATCH /zoos/{id}: update the information of a specified zoo (provide some information about the zoo) 
DELETE /zoos/{id}: delete a zoo 
GET /zoos/{id}/animals: list All animals in a given zoo

Get all employees in a department

GET /employee/getByDeptId used to be more casual

GET /departments/{id}/employees restful风格

3> Request parameters

Not fixed, it depends on the function of the interface, it can be said that it is determined by the demand

4> Request Response

​RESTful
has made a detailed agreement on the response value:

GET /collection: returns a list (array) of resource objects 
GET /collection/resource: returns a single resource object 
POST /collection: returns a newly generated resource object 
PUT /collection/resource: returns a complete resource object 
PATCH /collection/resource: returns Complete resource object 
DELETE /collection/resource: returns an empty document

The above data returns are all in Json format.

The real development and the specific response data are mainly based on the company's regulations/operational needs.

Related expansion

HTTP response status code

200 OK - [GET]: The server successfully returned the data requested by the user.

201 CREATED - [POST/PUT/PATCH]: The user successfully created or modified data.

202 Accepted - [ ]: Indicates that a request has been queued in the background (asynchronous task)

204 NO CONTENT - [DELETE]: The user deletes data successfully.

400 INVALID REQUEST - [POST/PUT/PATCH]: There is an error in the request sent by the user, and the server did not create or modify data. This operation is idempotent.

401 Unauthorized - [ ]: Indicates that the user does not have permission (token, username, password error).

403 Forbidden - [ ] indicates that the user is authorized (as opposed to a 401 error), but access is forbidden.

404 NOT FOUND - [ ]: The request sent by the user is for a record that does not exist, and the server has not performed any operation, which is idempotent.

406 Not Acceptable - [GET]: The format requested by the user is not available (for example, the user requests JSON format, but only XML format).

410 Gone -[GET]: The resource requested by the user is permanently deleted and will not be obtained again.

422 Unprocesable entity - [POST/PUT/PATCH] A validation error occurred while creating an object.

500 INTERNAL SERVER ERROR - [*]: An error occurred on the server, and the user will not be able to determine whether the request was successful.

resource representation

For example, text can be expressed in txt format, HTML format, XML format, JSON format, or even binary format; pictures can be expressed in JPG format or PNG format.

Its specific form of expression should be specified in the header information of the HTTP request with the Accept and Content-Type fields, and these two fields are the description of the "expression".

accept:application/json content-type:application/json

The difference between Accept and Content-Type 1. Accept belongs to the request header, and Content-Type belongs to the entity header. Http headers are divided into general headers, request headers, response headers and entity headers. The http header structure of the requester: general header|request header|entity header The http header structure of the responder: general header|response header|entity header

2.Accept represents the data type that the sender (client) wants to accept. For example: Accept: application/json; means that the data type that the client wants to accept is json type, and the background returns json data

Content-Type represents the data type of the entity data sent by the sender (client|server). For example: Content-Type: application/json; means that the data format sent by the sender is json, and the background must use this format to receive the data sent by the front end.

 

Caution

REST is just a design style, not a standard. It just provides a set of design principles and constraints, and the specific operation is combined with company requirements/project requirements.

RESTful framework

The common ones are SpringMVC, jersey, play

API testing tool

Postman, Insomnia

RESTful interface practice

project preparation

1> Build a standard Springboot project, using the web environment

rely

 <!-- SpringBoot的依赖配置-->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.3</version>
    <relativePath/>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.20</version>
        <scope>provided</scope>
    </dependency>


</dependencies>

2> configure application.properties

server.port=80

3> Edit entity class, startup class, controller class

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
    private Long id;
    private String name;
    private int age;
}

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

@Controller
public class EmployeeController {
}

interface design

1. Get all employees

/**
 * 需求: 查询所有员工数据
 * 1>请求路径:  确定资源: /employees
 * 2>请求方式: GET
 * 3>请求参数: 无
 * 4>请求响应:  List<Employee> Json格式
*/
@RequestMapping(value = "/employees", method = RequestMethod.GET)
@ResponseBody
public List<Employee> list(){
    return Arrays.asList(new Employee(1L, "dafei", 18),
                         new Employee(2L, "xiaofei", 17) );
}

test

URL:http://localhost:80/employees

Request method: GET

2. Add an employee

/**
 * 需求: 添加一个员工信息
 * 1>请求路径:  确定资源: /employees
 * 2>请求方式: POST
 * 3>请求参数: 员工相关信息(属性)
 * 4>请求响应:  Employee  Json格式
*/
@RequestMapping(value = "/employees", method = RequestMethod.POST)
@ResponseBody
public Employee add(Employee employee){
    employee.setId(1L);  //假装添加到数据,新增id为1L
    return employee;
}

test

URL:http://localhost:80/employees

Request method: POST

Parameters: name, age

3. Update employee data

/**
 * 需求: 更新一个员工信息
 * 1>请求路径:  确定资源: /employees
 * 2>请求方式: PUT
 * 3>请求参数: 员工相关信息(属性)
 * 4>请求响应:  Employee  Json格式
*/
@RequestMapping(value = "/employees", method = RequestMethod.PUT)
@ResponseBody
public Employee update(Employee employee){
    employee.setName(employee.getName() + "_update");
    return employee;
}

test

URL:http://localhost:80/employees

Request method: PUT

Parameters: id, name, age

4. Delete an employee

Requirements, after the operation is successful, the operation status prompt will be returned, and an additional custom state encapsulation object is required (unified return value)

@Setter
@Getter
public class JsonResult{

    private int code;  //状态码
    private String msg;//提示信息
    private Object data;//结果数据
    public JsonResult(int code, String msg, Object data){
        this.code = code;
        this.msg = msg;
        this.data = data;
    }
    public static JsonResult success(){
        return new JsonResult(200, "操作成功", null);
    }
    public static JsonResult error(String msg){
        return new JsonResult(500, msg, null);
    }
}
/**
 * 需求: 删除一个员工信息
 * 1>请求路径:  确定资源: /employees
 * 2>请求方式: DELETE
 * 3>请求参数: id
 * 4>请求响应: 状态提示(成功/失败)
*/
@RequestMapping(value = "/employees", method = RequestMethod.DELETE)
@ResponseBody
public JsonResult delete(Long id){
    return JsonResult.success();
}

test

URL:http://localhost:80/employees

Request method: DELETE

Parameter: id

5. Get information about an employee

/**
 * 需求: 查询指定id的员工数据
 * 1>请求路径:  确定资源: /employees
 * 2>请求方式: GET
 * 3>请求参数: id
 * 4>请求响应:  Employee Json格式
 */
@RequestMapping(value = "/employees", method = RequestMethod.GET)
@ResponseBody
public Employee detail(Long id){
    return new Employee(id, "dafei", 18);
}

When the project starts, an error is reported directly, saying that the mapping mapping is repeated

Analyze the reasons


    /**
     *
     * 查询所有员工与查询某个员工, 使用路径: /employees   使用方法: GET  都相同
     * 此时在springmvc语法中,2个请求是不允许共存的。此时怎么办?
     *
     * 方案1:使用多级路径方式区分, 比如: /employees/detail
     * 方案2:参数路径的方式
     * 参数路径:请求映射接口中,将请求参数作为路径的一部分 
     *    比如:/employees/{id}      {id}  路径参数的占位符
     *    注意:客户发起请求时:
               url路径写法: http://localhost:8080/employees/1      其中 1 是路径参数
     *
     * 接口想要获取路径中参数,需要使用:@PathVariable 注解
     *   @PathVariable 作用:将url路径上参数解析并赋值到请求映射方法的形式参数
     *   注意: 如果路径参数的占位符跟请求映射方法的形式参数名不一致,需要使用注解属性明确指定
     *   "/employees/{eid}"    --->   @PathVariable("eid")
     *
     */

plan 1:

@RequestMapping(value = "/employees/detail", method = RequestMethod.GET)
@ResponseBody
public Employee detail(Long id){
    return new Employee(id, "dafei", 18);
}

test

URL:http://localhost:80/employees/detail

Request method: GET

Parameter: id

Scenario 2:

@RequestMapping(value = "/employees/{id}", method = RequestMethod.GET)
@ResponseBody
public Employee detail(@PathVariable Long id){
    return new Employee(id, "dafei", 18);
}

test

URL:http://localhost:80/employees/1

Request method: DELETE

parameter path expansion 

page request interface

Requirements: There are 5 buttons on the page, click to initiate an asynchronous request, and access the corresponding restful interface

1> import jquery.js

2> Write info.html page

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/jquery/jquery.min.js"></script>

    <script>
        $(function () {
            $("#btn1").click(function () {
                $.get("/employees/1",function (data) {
                    console.log(data);
                })

            })

            $("#btn2").click(function () {
                $.get("/employees",function (data) {
                    console.log(data);
                })
            })

            $("#btn3").click(function () {

                $.post("/employees", {name:"dafei", age:18}, function (data) {
                    console.log(data);
                })


            })
            $("#btn4").click(function () {

                $.ajax({
                    url:"/employees",
                    type:"PUT",
                    data:{id:1, name:"dafei", age:18},
                    success:function (data) {
                        console.log(data);
                    }
                })

            })
            $("#btn5").click(function () {
                $.ajax({
                    url:"/employees",
                    type:"DELETE",
                    data:{id:1},
                    success:function (data) {
                        console.log(data);
                    }
                })
            })
        })
    </script>
</head>
<body>
<button id="btn1">查单个</button><br>
<button id="btn2">查所有</button><br>
<button id="btn3">添加</button><br>
<button id="btn4">更新</button><br>
<button id="btn5">删除</button><br>
</body>
</html>

3> Access, click the button in turn

Notice

SpringMVC does not support the processing of put requests by default, and it is necessary to configure filters for processing put or patch requests

<filter>
	<filter-name>httpPutFormContentFilter</filter-name>
	<filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>

<filter-mapping>
	<filter-name>httpPutFormContentFilter</filter-name>
	<servlet-name>springMVC</servlet-name>
</filter-mapping>

Simplified RESTful interface

@RestController

Composed of @Controller + @ResponseBody, pasted on the controller class

@PathVariable

Placeholder parameters in the URL can be bound to the input parameters of the controller processing method through @PathVariable

The {xxx} placeholder in the URL can be bound to the input parameter of the operation method through @PathVariable(“xxx”).

Paste on request mapping method parameters

@GetMapping is attached to the request mapping method, which is equivalent to: @RequestMapping(method = RequestMethod.GET)

@PostMapping

Pasted on the request mapping method, equivalent to: @RequestMapping(method = RequestMethod.POST)

@PutMapping

Paste on the request mapping method, equivalent to: @RequestMapping(method = RequestMethod.PUT)

@DeleteMapping

Paste on the request mapping method, equivalent to: @RequestMapping(method = RequestMethod.DELETE)

@RestController  //等价于:@ResponseBody + @Controller
@RequestMapping("employees")
public class EmployeeController {
    @GetMapping
    public List<Employee> list(){
        return Arrays.asList(new Employee(1L, "dafei", 18),
                new Employee(2L, "xiaofei", 17) );
    }
    @GetMapping("/{id}")
    public Employee detail(@PathVariable Long id){
        return new Employee(id, "dafei", 18);
    }
    @PostMapping
    public Employee add(Employee employee){
        employee.setId(1L);
        return employee;
    }
    @PutMapping
    public Employee update(Employee employee){
        employee.setName(employee.getName() + "_update");
        return employee;
    }
    @DeleteMapping
    public JsonResult delete(Long id){
        return JsonResult.success();
    }
}

RequestMapping annotation attribute

value/path : mapping path; method : way to limit the request, enumeration:

public enum RequestMethod {
    GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
}

params : Limit the parameters to be processed in the request, only requests matching the parameters will be processed by this method;

/**
 * @RequestMapping(value = "/test", params = {"name"})  要求请求必须带上name参数
 * @RequestMapping(value = "/test", params = {"name=dafei"})  要求请求必须带上name参数,并且值为dafei
 */
@RequestMapping(value = "/test", params = {"name=dafei"})
@ResponseBody
public String test(){
}    

headers : Limit the request header information of the request to be processed. Only requests matching the content of the request header will be processed by this method;

@RequestMapping(value = "/test2", headers = {"accept=application/json"})
@ResponseBody
public String test2(){
    return "ok--json";
}

@RequestMapping(value = "/test2", headers = {"content-type=application/xml"})
@ResponseBody
public String test3(){
    return "ok--xml";
}

consumes : limit the request header information to be processed, and clearly specify the type of parameters carried by the client

//等价于:@RequestMapping(value = "/test2", headers = {"content-type=application/json"})
@RequestMapping(value = "/test2", consumes = {"application/json"})
@ResponseBody
public String test4(){
    return "ok--json";
}

produces : Limit the request header information to be processed, and clearly specify that the client expects the server to respond with the specified parameter type

//等价于:@RequestMapping(value = "/test2", headers = {"accept=application/json"})
@RequestMapping(value = "/test2", produces = {"application/json"})
@ResponseBody
public String test5(){
    return "ok--json";
}

Summarize

RESTful interface design is just such a thing

1> Request path

Determine the specific operation resource, and combine the requirements, you can add the prefix and suffix of the path appropriately, or use the parameter path method

2> Request method

According to the actual function of the interface, find the appropriate method for the CRUD of resources

Resources from scratch: POST

Resource from existence to non-existence: DELETE

Resource from state A to state B: PUT

Resource state unchanged: GET

3> Request parameters

According to the function of the interface, the parameters are passed in on demand

4> Request Response

According to the interface implementation and client call requirements, the specific return value is determined. It is recommended to use the JSON format.

To sum up one sentence: RESTful is an interface design style. It is recommended that you abide by it. During development, it should be handled flexibly in combination with the actual situation under the premise of compliance.

Homework

Query all employees under a certain department

/departments/{id}/employees

Query the collection of all employee salaries

/employees/salaries

Query an employee's salary for a certain month

/employees/{id}/salaries/{month}

User login operation

/users/login --POST

User logout operation

/users/logout --DELETE

Search by username

/users/{name}

Search by age

/users/{age}

Guess you like

Origin blog.csdn.net/langfeiyes/article/details/122871361
Recommended