restful api style

Introduction

REST: English representational state transfer is literally translated as presentation layer state transfer, or representational state transfer; Rest is an architectural style, a design style, and a kind of idea of ​​web services; at the same time, Rest is not for a certain programming language.

Take webService as an example for a simple explanation.

Non-Rest design, we used to write like this:

http://localhost:8080/admin/getUser (查询用户)

http://localhost:8080/admin/addUser (新增用户)

http://localhost:8080/admin/updateUser (更新用户)

http://localhost:8080/admin/deleteUser (删除用户)

Summary: Do different things with different URLs (mostly using verbs).

Rest Architecture:

GET http://localhost:8080/admin/user (查询用户)

POST http://localhost:8080/admin/user (新增用户)

PUT http://localhost:8080/admin/user (更新用户)

DELETE http://localhost:8080/admin/user (删除用户)

To summarize: URLs only specify resources, with HTTP method verbs for different operations. Use HTTP STATUS/CODE to define the result of the operation.

Restful: A web service that adheres to the rest style can be called Restful.

Why do you need Restful?

URLs are highly readable and self-describing

Normalize the request process and return results

Loose coupling between resource description and view

OpenAPI can be provided to facilitate third-party system integration and improve interoperability

Provide a stateless service interface, reduce complexity, and improve the horizontal scalability of applications

/versionnumber/resourcepath

/v1/tags/{
    
    tag_id}

/v1/users?[&keyword=xxx][&enable=1][&offset=0][&limit=20]

1. Version number
Naming the version number can solve the problem of version incompatibility. A practical way to design a RESTful API is to use the version number. In general, we will keep the old version number in the url and be compatible with multiple versions at the same time

【GET】 /v1/users/{
    
    user_id} // 版本 v1 的查询用户列表的 API 接口

【GET】 /v2/users/{
    
    user_id} // 版本 v2 的查询用户列表的 API 接口

2. The resource path
URI cannot contain verbs, only nouns (when naming nouns, use lowercase, numbers and underscores to distinguish multiple words).

The paths to the resources should be as follows, from root to child:

/{
    
    resources}/{
    
    resource_id}/{
    
    sub_resources}/{
    
    sub_resource_id}/{
    
    sub_resource_property}

【POST】 /v1/users/{
    
    user_id}/roles/{
    
    role_id} // 添加用户的角色

Sometimes, when a resource change is difficult to name using a standard RESTful API, consider using some special actions naming.

/{
    
    resources}/{
    
    resource_id}/actions/{
    
    action}

【PUT】 /v1/users/{
    
    user_id}/password/actions/modify // 密码修改

3. Request method

【GET】 /users # 查询用户信息列表

【GET】 /users/1001 # 查看某个用户信息

【POST】 /users # 新建用户信息

【PUT】 /users/1001 # 更新用户信息(全部字段)

【PATCH】 /users/1001 # 更新用户信息(部分字段)

【DELETE】 /users/1001 # 删除用户信息

【PATCH】一般不用,用【PUT】

4. Query parameters
The RESTful API interface should provide parameters to filter the returned results.

【GET】 /{
    
    version}/{
    
    resources}/{
    
    resource_id}?offset=0&limit=20

5. Response parameter
JSON format (code, data, msg)

6.
Status code It is important to use the appropriate status code, and should not all return status code 200

Status code, which can expand its own status code according to the project according to the following standards:

200~299段 表示操作成功:

200 操作成功,正常返回

201 操作成功,已经正在处理该请求

300~399段 表示参数方面的异常

300 参数类型错误

301 参数格式错误

302 参数超出正常取值范围

303 token过期

304 token无效

400~499段 表示请求地址方面的异常:

400 找不到地址

500~599段 表示内部代码异常:

500 服务器代码异常

7. Complete case

UserController.java

@RestController(/v1)

@API(tag=”用户相关接口”)

public class UserController {
    
    
 

    @Autowired

    private UserJPARepository userJPARepository;


    /**

     * 查询用户列表

     * @return

     */

    @GetMapping(value = "/user")

    public List<User> findUserList(){
    
    

        return userJPARepository.findAll();

    }


    /**

     * 根据Id查询一个用户

     * @param id

     * @return

     */

    @GetMapping(value = "/user/query/{id}")

    public User findUserOne(@PathVariable("id") Integer id){
    
    

        return userJPARepository.findOne(id);

    }


    /**

     * 添加用户

     * @param name

     * @param age

     * @param country

     * @return

     */


    @PostMapping(value = "/user")

    public User addUser(@RequestParam("name") String name, @RequestParam("age") int age,

                        @RequestParam("country") String country){
    
    

        User user = new User();

        user.setName(name);

        user.setAge(age);

        user.setCountry(country);

        return userJPARepository.save(user);

    }

    /**

     * 删除用户

     * @param id  用户编号

     * @return

     */

    @DeleteMapping(value = "/user/{id}")

    public  List<User> deleteUser(@PathVariable("id") Integer id){
    
    

        userJPARepository.delete(id);

        return userJPARepository.findAll();

    }

    /**

     * 更新用户

     * @param id

     * @param name

     * @param age

     * @param country

     * @return

     */

    @PutMapping(value = "/user/{id}")

    public User updateUser(@PathVariable("id") Integer id, @RequestParam("name") String name,

                           @RequestParam("age") int age, @RequestParam("country") String country){
    
    

        User user = userJPARepository.findById(id);

        user.setName(name);

        user.setAge(age);

        user.setCountry(country);

        return userJPARepository.save(user);

    }

    /**

     * 根据国家查询用户

     * @param country

     * @return

     */

    @GetMapping(value = "/user/{country}")

    public List<User> findByCountry(@PathVariable("country") String country){
    
    

        return userJPARepository.findByCountry(country);

    }

}

Guess you like

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