SpringBoot入门实践(四)-RESTful API 最佳设计

6,856 阅读4分钟

 我的博客:兰陵笑笑生,欢迎浏览博客!

 上一章 SpringBoot入门实践(三)-工程结构与常用注解当中,我们介绍了SpringBoot的项目的工程结构和一些常用的注解。本章简单的讲一讲API的设计。

 网上有非常多的关于API设计的介绍,本章内容从自己的实际经验简单介绍如何更好的设计API。

API的有什么关键的要求

1 任何客户端都能够调用,需要一个标准,使得客户端和服务端达成一致,必须简单

2 api独立于客户端,api的发展,现有的客户端可以继续运行,不需要修改。

RESTful URLS

REST API 是围绕这资源设计的,资源有一个唯一的标识符,并且使用JSON

使用HTTP 定义资源的操作

  1. GET 检所获取资源
  2. POST 创建资源,当然POST也可以用来触发实际上不创建资源的操作
  3. PUT 创建或者更新
  4. DELETE 移除

SpringBoot与RESTful

 在springBoot当中提供了很多的注解,使用这些注解就很容易的实现RESTful的api

@RequestMapping:

 该注解有6个参数:

  • value/path :路径名称
  • params :请求的参数
  • method :方法类型 GET、POST、PUT、DELETE 等
  • headers: request 中必须包含某些指定的 header 值,才能让该方法处理请求。
  • consumes : (Content-Type),例如application/json,text/html;

例如请求 表示一個GET请求:

@RequestMapping(path = "/list",method = RequestMethod.GET, consumes ="application/json")
public HttpResponse list() { 
    List<User> user = new ArrayList<>(userMap.values());   
    return HttpResponse.ok().setData(user);
}

@PostMapping

  等价于@RequestMapping(path = "/**",method = RequestMethod.POST)

@GetMapping

  等价于@RequestMapping(path = "/**",method = RequestMethod.GET)

@DeleteMapping

  等价于@RequestMapping(path = "/**",method = RequestMethod.DELETE)

@PutMapping

  等价于@RequestMapping(path = "/**",method = RequestMethod.PUT)

具体的设计

 URL的定义在每个公司中都不一样,这里简单给出一些我自己的实际经验,url路径定义:

1 url理解简单

2 api有版本控制, 版本控制可以快速迭代并避免无效的请求访问已更新的接入点

http://www.example.com/api/v{version}/模块名称/操作名称

获取单个用户

GET /api/v1/user/get/1

或者

GET /api/v1/user/1

分页或者全部的查询,输入的参数是JSON

POST /api/v1/user/list

这个新增和更新一般都是一个api,当然也可以使用PUT

POST /api/v1/user/save

删除用户资源

DELETE /api/v1/user/delete/12

或者

DELETE /api/v1/user/12

public class User {  
    private Long id; 
    private String userName; 
    private Long age;
    
    ...
        
}

自定义统一返回结果

package com.miroservice.chapter2.common;
import com.fasterxml.jackson.annotation.JsonInclude;
import java.io.Serializable;
import java.util.*;


@JsonInclude(JsonInclude.Include.NON_NULL)
public class HttpResponse implements Serializable { 
    
    private long code;  
    private String message; 
    private Long total;  
    private Object data;  
    private List<Object> table;  
    private String requestid;  
    public static final long CODE_SUCCESS = 200;  
    public static final long CODE_ERROR = 500;  
    public static final long CODE_VALIDATE_FAILED = 404;  
    public static final long CODE_UNAUTHORIZED = 401;  
    public static final long CODE_FORBIDDEN = 403;    
    public HttpResponse() {    
        this(200, (String) null);    } 
    public HttpResponse(long code, String message) {    
        this.code = CODE_SUCCESS;     
        this.code = code;      
        this.message = message;      
        this.requestid = UUID.randomUUID().toString().replaceAll("-", "");  
    }   
    public static HttpResponse error(String message) {   
        return new HttpResponse(500, message);  
    }  
    public HttpResponse setData(Object data) {       
        this.data = data;    
        return this;  
    }  
    public HttpResponse data(Object data) {  
        return this.setData(data);  
    }
    public HttpResponse addListItem(Object item) {   
        if (this.table == null) {       
            this.table = new ArrayList();     
        }     
        this.table.add(item);       
        
        return this;  
    }  
    public HttpResponse setTotal(Long total) {    
        this.total = total;    
        return this;   
    }    
    public HttpResponse setTotal(Integer total) {    
        this.total = (long) total;      
        return this; 
    }   
    public static HttpResponse ok() {  
        return new HttpResponse();  
    }  
    public HttpResponse set(String field, String value) {  
        if (this.data == null || !(this.data instanceof Map)) {    
            this.data = new HashMap();    
        }      
        ((Map) this.data).put(field, value); 
        return this;
    }   
    public long getCode() {   
        return this.code;   
    }   
    public HttpResponse setCode(long code) {    
        this.code = code;      
        return this; 
    }    public String getMessage() {       
        return this.message;  
    }   
    public HttpResponse setMessage(String message) {     
        this.message = message;       
        return this;   
                                               
    }   
    public Long getTotal() {     
        return this.total == null && this.table != null ?     Long.valueOf(String.valueOf(this.table.size())) : this.total;   
    }   
    public Object getData() {  
        return this.data;   
                                 }  
    public List<Object> getTable() {      
        return this.table; 
    }  
    public HttpResponse setTable(List table) {    
        this.table = table;   
        return this;  
    }   
    public HttpResponse table(List table) {    
        return this.setTable(table); 
    }  
    public String getRequestid() {     
        return this.requestid; 
    }  
    public HttpResponse setRequestid(String requestid) {     
        this.requestid = requestid;    
        return this;    }
}

 Controller层

/** 
* 1 api 的设计 一眼明了
* 2 有版本
* 3 控制层统一返回自定义的结果 
*/
@RestController
@RequestMapping("/api/v1/user")
public class UserController { 
    static Map<Long, User> userMap = new HashMap<Long, User>();   
    /**   
    * 列表请求 
    * @return 
    */   
   @RequestMapping(method = RequestMethod.GET, consumes = "application/json")                @GetMapping(consumes = "application/json")    
    public HttpResponse list() {     
        List<User> user = new ArrayList<>(userMap.values());     
        return HttpResponse.ok().setData(user);  
    }  
    /**   
    * 保存  
    * @param user   
    * @return  
    */  
    @PostMapping("/save")   
    public HttpResponse save(@RequestBody User user) {      
        userMap.put(user.getId(), user);      
        return HttpResponse.ok();    }  
    /**     
    * 获取单个用户  
    * @param id   
    * @return   
    */  
    @GetMapping("/get/{id}") 
    public HttpResponse get(@PathVariable Long id) {   
        final User user = userMap.get(id);    
        return HttpResponse.ok().setData(user);    } 
    /**   
    * 删除  
    * @param id   
    * @return  
    */  
    @DeleteMapping("/delete/{id}")   
    public HttpResponse delete(@PathVariable Long id) {  
        userMap.remove(id);     
        return HttpResponse.ok(); 
    }
    
}

 以上就是本期的分享,你还可以关注本博客的#Spring Boot入门实践系列!#

 参考: #微软的API实践#     #Spring REST DOC#

本文由博客一文多发平台 OpenWrite 发布!