HTTP规范 RESTful API设计_restful api接口规范
一.请求规范
1.请求方法
-
GET:获取资源
-
POST:创建资源
-
PUT:更新完整资源
-
PATCH:部分更新资源
-
DELETE:删除资源
2.请求头
-
Content-Type
: 指定请求体格式 (如application/json
) -
Accept
: 指定期望的响应格式 -
Authorization
: 认证凭证 (如Bearer
) -
User-Agent
: 客户端标识
3.URL规范
-
使用小写字母和连字符(-)
-
资源使用复数名词 (如
/users
) -
查询参数使用小驼峰 (如
?pageSize=10
)
4.请求体
-
JSON格式为主
-
字段名使用小驼峰命名法
-
避免冗余数据
二.响应规范
1.状态码
-
2xx 成功
-
200 OK - 通用成功
-
201 Created - 资源创建成功
-
204 No Content - 无返回内容
-
-
3xx 重定向
-
301 Moved Permanently - 永久重定向
-
302 Found - 临时重定向
-
-
4xx 客户端错误
-
400 Bad Request - 请求错误
-
401 Unauthorized - 未认证
-
403 Forbidden - 无权限
-
404 Not Found - 资源不存在
-
-
5xx 服务端错误
-
500 Internal Server Error - 服务器错误
-
503 Service Unavailable - 服务不可用
-
2.响应头
-
Content-Type
: 响应体格式 (如application/json
) -
Cache-Control
: 缓存控制 -
ETag
: 资源版本标识
3.响应体
{ \"code\": 200, \"message\": \"success\", \"data\": { }, \"pagination\": { \"total\": 100, \"page\": 1, \"pageSize\": 10 }, \"error\": { \"code\": \"ERROR_CODE\", \"details\": \"详细错误信息\" }}
请求示例
GET /v1/users?page=1&pageSize=10 HTTP/1.1Host: api.example.comAccept: application/jsonAuthorization: Bearer xxxxxx
成功响应示例
{ \"code\": 200, \"message\": \"success\", \"data\": [ {\"id\": 1, \"name\": \"张三\"}, {\"id\": 2, \"name\": \"李四\"} ], \"pagination\": { \"total\": 100, \"page\": 1, \"pageSize\": 10 }}
三.RESTful api
RESTful API 是一种基于 HTTP 协议的 API 设计风格,遵循 REST (Representational State Transfer) 架构原则。
1. 基本原则
-
无状态性:每个请求应包含处理所需的所有信息
-
资源导向:API 围绕资源而非动作设计
-
统一接口:使用标准的 HTTP 方法 (GET, POST, PUT, DELETE 等)
-
可缓存性:响应应明确表明是否可缓存
-
分层系统:客户端无需知道是否直接连接到最终服务器
2. 资源命名规范
1.URL 结构
https://api.example.com/v1/resources/{id}/sub-resources
2.命名规则
-
使用名词复数形式表示资源集合
-
/users
而不是/getUsers
-
-
使用小写字母和连字符(-)
-
/user-roles
而不是/userRoles
-
-
避免在 URL 中使用动词
-
错误示例:
/getUserById
-
正确示例:
/users/{id}
-
3. HTTP 方法使用
GET /users
POST /users
PUT /users/{id}
PATCH /users/{id}
DELETE /users/{id}
HEAD /users
OPTIONS /users
四.用普通的Webservlet实现登录
1.entity
创建一个用户类,包含id,name,age,password。
package entitty;public class User { int id; String name; int age; String password; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return \"User{\" + \"id=\" + id + \", name=\'\" + name + \'\\\'\' + \", age=\" + age + \", password=\'\" + password + \'\\\'\' + \'}\'; }}
2.JDBC
在与数据库进行操作时,链接和关闭可以单独列出来。这里数据库名为users,表格名为users
package JDBC;import java.sql.*;public class JDBCUtil { static { try { Class.forName(\"com.mysql.cj.jdbc.Driver\"); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } } private static final String URL = \"jdbc:mysql://localhost:3306/users\"; private static final String USER = \"root\"; private static final String PASSWORD = \"123456\"; public static Connection getConnection() { Connection connection; try { connection = DriverManager.getConnection(URL, USER, PASSWORD); } catch (SQLException e) { throw new RuntimeException(e); } return connection; } public static void close(ResultSet resultSet, PreparedStatement preparedStatement, Connection connection) { try { if (resultSet != null) { resultSet.close(); } if (preparedStatement != null) { preparedStatement.close(); } if (connection != null) { connection.close(); } } catch (SQLException e) { throw new RuntimeException(e); } }}
这里要在static里写一个Class.forName,确保tomcat可以找i到程序。
3.dao
实现与数据库的操作,这里我们需要根据传入的name来返回一个User对象,如果没有找到,则返回null。
package dao;import entitty.User;public interface LoginDao { User login(String nam);}
package dao.impl;import JDBC.JDBCUtil;import dao.LoginDao;import entitty.User;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;public class LoginDaoImpl implements LoginDao { Connection connection; PreparedStatement preparedStatement; ResultSet resultSet; @Override public User login(String name) { User user = new User(); connection = JDBCUtil.getConnection(); String sql = \"select * from users where name = ?\"; try { preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1, name); resultSet = preparedStatement.executeQuery(); if (resultSet.next()) { user.setId(resultSet.getInt(\"id\")); user.setName(resultSet.getString(\"name\")); user.setAge(resultSet.getInt(\"age\")); user.setPassword(resultSet.getString(\"password\")); return user; } } catch (SQLException e) { throw new RuntimeException(e); } finally { JDBCUtil.close(resultSet, preparedStatement, connection); } return null; }}
4.service
service层主要是进行逻辑操作,在登录中,需要对照数据库中的name对应的password和传入的password是否相同。是,返回Users对象;否,返回null;
package service;import entitty.User;public interface LoginService { User login(String name, String password);}
package service.Impl;import dao.LoginDao;import dao.impl.LoginDaoImpl;import entitty.User;import service.LoginService;public class LoginServiceImpl implements LoginService { LoginDao loginDao = new LoginDaoImpl(); @Override public User login(String name, String password) { User user = loginDao.login(name); if (user != null && user.getPassword().equals(password)) { return user; } else { return null; } }}
5.contorller
controller与网路进行交互
package controller;import entitty.User;import jakarta.servlet.ServletException;import jakarta.servlet.annotation.WebServlet;import jakarta.servlet.http.HttpServlet;import jakarta.servlet.http.HttpServletRequest;import jakarta.servlet.http.HttpServletResponse;import jakarta.servlet.http.HttpSession;import service.LoginService;import service.Impl.LoginServiceImpl;import java.io.IOException;import java.io.PrintWriter;@WebServlet(\"/users\")public class LoginController extends HttpServlet { LoginService loginService = new LoginServiceImpl(); public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType(\"text/plain;charset=utf-8\"); PrintWriter out = response.getWriter(); HttpSession session = request.getSession(); String name = request.getParameter(\"name\"); String password = request.getParameter(\"password\"); User user = loginService.login(name, password); if (user != null) { System.out.println(user.toString()) response.sendRedirect(\"/index.jsp\"); } else { out.println(\"Not found\"); } }}
传入name和password,如果成功,则重定向到index.jsp。失败则显示Not found。