【接口篇】SpringBoot 快速实践 RESTful API 架构风格

什么是 RESTful API

官网地址:https://restfulapi.cn/

  • REST 是 Representational State Transfer 的缩写,如果一个架构符合 REST 原则,就称它为 RESTful 架构;
  • RESTful 架构可以充分的利用 HTTP 协议的各种功能,是 HTTP 协议的最佳实践;
  • RESTful API 是一种软件架构风格、设计风格,可以让软件更加清晰,更简洁,更有层次,可维护性更好;

API 请求

HTTP 动词

GET:   读取(Read)
POST:  新建(Create)
PUT:   更新(Update)
PATCH: 更新(Update),通常是部分更新
DELETE:删除(Delete)

请求设计

请求 = 动词 + 宾语

  • 动词 使用五种 HTTP 方法,对应 CRUD 操作;
  • 宾语 URL 应该全部使用名词复数,可以有例外,比如搜索可以使用更加直观的 search;
  • 过滤信息(Filtering) 如果记录数量很多,API 应该提供参数,过滤返回结果。 ?limit=10 指定返回记录的数量 ?offset=10 指定返回记录的开始位置;

API 响应

状态码

五大类状态码,总共100多种,覆盖了绝大部分可能遇到的情况。每一种状态码都有约定的解释,客户端只需查看状态码,就可以判断出发生了什么情况。API 不需要1xx状态码;

1xx:相关信息
2xx:操作成功
3xx:重定向
4xx:客户端错误
5xx:服务器错误

响应设计

服务器回应数据

  • 客户端的每一次请求,服务器都必须给出回应。回应包括 HTTP 状态码和数据两部分;

  • 客户端请求时,要明确告诉服务器,接受 JSON 格式,请求的 HTTP 头的 ACCEPT 属性要设成 application/json

  • 服务端返回的数据,不应该是纯文本,而应该是一个 JSON 对象。服务器回应的 HTTP 头的 Content-Type 属性要设为 application/json;

SpringBoot 快速实践 RESTful

注解实现

Srping Boot 提供了与 Rest 操作方式(GET、POST、PUT、DELETE)对应的注解:

HTTP 动词 Srping Boot 注解 说明
GET @GetMapping 读取
POST @PostMapping 新建
PUT @PutMapping 更新
PATCH @PatchMapping 更新,通常是部分更新
DELETE @DeleteMapping 删除

实践 RESTful

根据 RESTful 风格设计编写用户操作的 RESTful API。

1.定义用户类

package com.csp.mingyue.api.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

/** @author Strive */
@Data
@ToString
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MingYueUser {
  private Long userId;
  private String username;
}

2.编写 Service

package com.csp.mingyue.api.service;

import cn.hutool.core.map.MapUtil;
import com.csp.mingyue.api.model.MingYueUser;
import java.util.Map;
import org.springframework.stereotype.Service;

/** @author Strive */
@Service
public class MingYueUserService {

  /** 模拟用户存储 */
  private static final Map<Long, MingYueUser> USER_MAP = MapUtil.newHashMap();

  static {
    USER_MAP.put(1L, MingYueUser.builder().userId(1L).username("mingyue").build());
  }

  /**
   * 根据用户ID查询用户信息
   *
   * @param userId 用户ID
   * @return 用户信息
   */
  public MingYueUser queryUserById(Long userId) {
    return USER_MAP.get(userId);
  }

  /**
   * 添加用户
   *
   * @param user 用户信息
   * @return 新用户ID
   */
  public Long addUser(MingYueUser user) {
    USER_MAP.put(2L, user);

    return user.getUserId();
  }

  /**
   * 更新用户
   *
   * @param user 用户信息
   */
  public String updateUser(MingYueUser user) {
    MingYueUser mingYueUser = USER_MAP.get(user.getUserId());

    USER_MAP.put(user.getUserId(), user);

    return mingYueUser.getUsername() + " 更新为:" + user.getUsername();
  }

  /**
   * 根据用户ID删除用户
   *
   * @param userId 用户ID
   */
  public String deleteUser(Long userId) {
    int size = USER_MAP.size();

    USER_MAP.remove(userId);

    return "原" + size + "用户,删除后还有" + USER_MAP.size();
  }
}

3.编写 Controller

package com.csp.mingyue.api.controller;

import com.csp.mingyue.api.model.MingYueUser;
import com.csp.mingyue.api.service.MingYueUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
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.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/** @author Strive */
@RestController
@RequiredArgsConstructor
@RequestMapping("/user")
public class MingYueUserController {

  private final MingYueUserService mingYueUserService;

  @GetMapping("/{userId}")
  public ResponseEntity<MingYueUser> queryUserById(@PathVariable Long userId) {
    return ResponseEntity.ok(mingYueUserService.queryUserById(userId));
  }

  @PostMapping
  public ResponseEntity<Long> addUser(@RequestBody MingYueUser user) {
    return ResponseEntity.ok(mingYueUserService.addUser(user));
  }

  @PutMapping
  public ResponseEntity<String> updateUser(@RequestBody MingYueUser user) {
    return ResponseEntity.ok(mingYueUserService.updateUser(user));
  }

  @DeleteMapping("/{userId}")
  public ResponseEntity<String> deleteUser(@PathVariable Long userId) {
    return ResponseEntity.ok(mingYueUserService.deleteUser(userId));
  }
}

4.测试接口

下面的 Json 数据复制进入 Json 文件,Apifox 导入类型选择 Openapi/Swagger 即可测试接口,或者直接码云下载 mingyue-springboot-api Demo

{
    "openapi": "3.0.1",
    "info": {
        "title": "mingyue-springboot-learning",
        "description": "",
        "version": "1.0.0"
    },
    "tags": [
        {
            "name": "mingyue-springboot-api"
        }
    ],
    "paths": {
        "/user/{userId}": {
            "get": {
                "summary": "根据用户ID获取用户信息",
                "x-apifox-folder": "mingyue-springboot-api",
                "x-apifox-status": "developing",
                "deprecated": false,
                "description": "",
                "tags": [
                    "mingyue-springboot-api"
                ],
                "parameters": [
                    {
                        "name": "userId",
                        "in": "path",
                        "description": "",
                        "required": true,
                        "example": "1",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "成功",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {}
                                },
                                "examples": {}
                            }
                        }
                    }
                }
            },
            "delete": {
                "summary": "根据用户ID删除用户",
                "x-apifox-folder": "mingyue-springboot-api",
                "x-apifox-status": "developing",
                "deprecated": false,
                "description": "",
                "tags": [
                    "mingyue-springboot-api"
                ],
                "parameters": [
                    {
                        "name": "userId",
                        "in": "path",
                        "description": "",
                        "required": true,
                        "example": "1",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "成功",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {}
                                },
                                "examples": {}
                            }
                        }
                    }
                }
            }
        },
        "/user": {
            "put": {
                "summary": "更新用户",
                "x-apifox-folder": "mingyue-springboot-api",
                "x-apifox-status": "developing",
                "deprecated": false,
                "description": "",
                "tags": [
                    "mingyue-springboot-api"
                ],
                "parameters": [
                    {
                        "name": "Content-Type",
                        "in": "header",
                        "description": "",
                        "required": false,
                        "example": "{{'application/json'}}",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "text/plain": {
                            "schema": {
                                "type": "string"
                            },
                            "example": "{\"userId\":2,\"username\":\"Strive Update\"}"
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "成功",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {}
                                },
                                "examples": {}
                            }
                        }
                    }
                }
            },
            "post": {
                "summary": "添加用户",
                "x-apifox-folder": "mingyue-springboot-api",
                "x-apifox-status": "developing",
                "deprecated": false,
                "description": "",
                "tags": [
                    "mingyue-springboot-api"
                ],
                "parameters": [
                    {
                        "name": "Content-Type",
                        "in": "header",
                        "description": "",
                        "required": false,
                        "example": "{{'application/json'}}",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "text/plain": {
                            "schema": {
                                "type": "string"
                            },
                            "example": "{\"userId\":2,\"username\":\"Strive\"}"
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "成功",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {}
                                },
                                "examples": {}
                            }
                        }
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {}
    }
}

你可能感兴趣的:(Spring,全家桶,spring,boot,restful,接口设计)