后端如何写好一个接口

什么是接口

  • API接口 是一组规则和协议,允许不同的软件应用程序之间进行交互和通信。它定义了如何请求服务、数据格式、返回值以及错误处理等方面的规范

实现目标

要写好一个接口(API),不仅需要具备一定的技术技能,还需要考虑设计、健壮性和易用性。总结16大字:功能明确、设计合理、性能优化、易于维护。

操作步骤

编写接口的详细步骤

1.明确需求:

  • 确定接口的具体功能。例如:是创建用户、更新数据还是执行某种业务逻辑。
    理解接口输入输出的需求(需要接收哪些参数,返回什么数据)。

2.设计接口:

  • URL 路径设计:接口路径应简洁清晰,遵循 RESTful 风格,使用名词来代表资源。

  • 定义参数:

    • 路径参数:用来在 URL 中传递动态的资源 ID,例如 /users/{id}。

    • 查询参数:用于筛选、排序等功能,例如 /users?page=2&size=10。

    • 请求体参数:对于 POST、PUT、PUT、DELETE请求,通常需要一个请求体传递数据。

        GET:获取资源
        POST:创建资源
        PUT:更新资源
        DELETE:删除资源
        例如:GET /users(获取用户列表)、POST /users(创建用户)、GET /users/{id}(根据用户 ID 获取用户详细信息)。
      
  • 请求格式:如果接口需要接收数据,通常使用 JSON 格式传递请求体的数据。例如,登录接口的请求体可以包含用户名和密码。

3.校验输入参数:

  • 对客户端传入的参数进行校验,确保数据合法、格式正确。
    • 例如,检查用户名是否为空,密码是否符合安全要求。

4.业务逻辑处理:

  • 在 Service 层 实现核心业务逻辑,例如注册用户、检查用户名是否重复、密码加密等。
  • DAO 层(数据访问层)负责与数据库交互,完成数据存储、更新、查询等操作。

5.错误处理:

  • 根据业务逻辑处理可能的错误场景,并返回合适的错误码和错误信息。
    • 例如,用户不存在、数据不合法、权限不足等。

6.返回响应:

  • 统一格式的响应体返回结果数据,包含 code(状态码)、message(说明信息)、data(具体数据,可能为空)。
  •   200 OK:请求成功。
      201 Created:资源成功创建。
      400 Bad Request:请求参数有误。
      401 Unauthorized:认证失败,用户未登录或凭证无效。
      403 Forbidden:用户无权限访问资源。
      404 Not Found:请求的资源不存在。
      500 Internal Server Error:服务器内部错误。
    
  • 示例响应:
{
  "code": 200,
  "message": "Registration successful",
  "data": null
}

7.测试接口:

  • 使用工具(如 Postman)或自动化测试脚本,测试接口的各类功能,确保其正常工作。
  • 包含正向测试(正常输入),和负向测试(异常输入,如缺少参数、参数格式错误等)。

8.编写文档:

  • 使用文档工具(如 Swagger)编写接口文档,描述请求路径、方法、参数说明、示例请求和响应。
  • 让其他开发者或前端人员了解如何使用接口。**

示例:(用户注册接口)

  1. Controller 层:负责接收客户端请求,调用 Service 层处理逻辑,返回响应结果。
// Controller 层,负责处理 HTTP 请求
@RestController // 标记为一个 RESTful 控制器
@RequestMapping("/api") // 为所有接口统一设置一个路径前缀
public class UserController {

    @Autowired // 自动注入 UserService
    private UserService userService;

    /**
     * 用户注册接口
     * @param userDTO 从请求体中接收的用户信息
     * @return 注册结果
     */
    @PostMapping("/register") // 映射 HTTP POST 请求到 /api/register
    public Result register(@RequestBody UserDTO userDTO) {
        // 校验输入参数是否合法
        if (userDTO.getUsername() == null || userDTO.getPassword() == null) {
            // 如果用户名或密码为空,返回 400 错误
            return Result.error(400, "用户名或密码不能为空");
        }

        // 调用 Service 层处理业务逻辑
        boolean isRegistered = userService.register(userDTO);

        // 根据业务逻辑结果返回响应
        return isRegistered ? Result.success("注册成功") : Result.error(409, "用户名已存在");
    }
}

  • @RestController:声明这是一个控制器,返回的结果会自动转换为 JSON。
  • @RequestBody:用于将请求体中的 JSON 数据自动绑定到 UserDTO 对象。
  • userService.register(userDTO):调用 Service 层注册逻辑。
  1. Service 层:定义业务逻辑接口,提供服务调用的入口。
// Service 层接口,定义注册相关的业务逻辑
public interface UserService {

    /**
     * 用户注册业务逻辑接口
     * @param userDTO 包含用户信息的对象
     * @return 是否注册成功
     */
    boolean register(UserDTO userDTO);
}

  • boolean register(UserDTO userDTO):定义一个注册方法,返回 true 表示成功,false 表示失败。
  1. ServiceImpl 层:实现 Service 层接口,编写具体的业务逻辑。
// Service 层实现类,具体实现业务逻辑
@Service // 标记为 Spring 的 Service 组件,表示这是一个服务
public class UserServiceImpl implements UserService {

    @Autowired // 自动注入 Mapper 层,用于数据库操作
    private UserMapper userMapper;

    /**
     * 实现用户注册逻辑
     * @param userDTO 包含用户信息的对象
     * @return 是否注册成功
     */
    @Override // 标注这是接口方法的实现
    public boolean register(UserDTO userDTO) {
        // 调用 Mapper 层,查询用户名是否已存在
        User existingUser = userMapper.findByUsername(userDTO.getUsername());
        if (existingUser != null) {
            // 如果用户已存在,返回 false 表示注册失败
            return false;
        }

        // 如果用户名不存在,调用 Mapper 层保存用户信息
        userMapper.save(userDTO);
        return true; // 返回 true 表示注册成功
    }
}

  • @Service:声明这是一个业务服务组件。
  • userMapper.findByUsername(userDTO.getUsername()):检查用户名是否已存在。
  • userMapper.save(userDTO):如果用户名不存在,保存新用户信息。
  1. Mapper 层:负责与数据库交互,执行 SQL 查询和插入操作。
// Mapper 层,负责与数据库交互
@Mapper // 标记为 MyBatis 的 Mapper,自动生成实现类
public interface UserMapper {

    /**
     * 根据用户名查询用户是否存在
     * @param username 要查询的用户名
     * @return 如果存在则返回用户对象,否则返回 null
     */
    @Select("SELECT * FROM users WHERE username = #{username}") // 使用 MyBatis 注解编写 SQL 查询语句
    User findByUsername(String username);

    /**
     * 保存用户信息到数据库
     * @param userDTO 包含用户信息的对象
     */
    @Insert("INSERT INTO users (username, password, email) VALUES (#{username}, #{password}, #{email})") // 插入用户信息
    void save(UserDTO userDTO);
}

  • @Mapper:表示这是 MyBatis 的 Mapper 接口,Spring 会自动实现接口的实现类。
  • @Select 和 @Insert:分别用于查询和插入 SQL 语句。
  • findByUsername:通过用户名查询用户信息。
  • save:将新用户信息插入到数据库中。
  1. DTO(数据传输对象):用于封装请求体中的数据。
// 数据传输对象,用于封装请求数据
@NoArgsConstructor//生成无参构造函数
@AllArgsConstructor//生成全参构造函数
@Data // 使用 @Data 注解自动生成 getter 和 setter 方法
public class UserDTO {
    private String username; // 用户名
    private String password; // 密码
    private String email;    // 邮箱
}

  1. Result(统一响应对象):用于统一处理返回的响应结果。
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data // 自动生成 getter、setter、toString、equals 和 hashCode 方法
@NoArgsConstructor // 生成无参构造函数
@AllArgsConstructor // 生成全参构造函数
public class Result {
    private Integer code; // 响应码,1 代表成功; 0 代表失败
    private String msg;   // 响应信息 描述字符串
    private Object data;  // 返回的数据

    // 增删改 成功响应
    public static Result success() {
        return new Result(1, "success", null);
    }

    // 查询 成功响应
    public static Result success(Object data) {
        return new Result(1, "success", data);
    }

    // 失败响应
    public static Result error(String msg) {
        return new Result(0, msg, null);
    }
}


  • @Data: 这个注解会为所有字段生成 getter 和 setter 方法,toString() 方法,以及 equals() 和 hashCode() 方法。这使得这个类更简洁,同时提供了常用的功能。

  • @NoArgsConstructor: 生成一个无参构造函数,可以方便地创建 Result 对象。

  • @AllArgsConstructor: 生成一个全参构造函数,可以通过提供所有字段的值来创建 Result 对象。

  • 响应方法:

    • public static Result success(): 创建一个表示成功但不带任何数据的响应。
    • public static Result success(Object data): 创建一个表示成功并包含数据的响应。
    • public static Result error(String msg): 创建一个表示失败并包含错误信息的响应。

架构

  • Controller 层:处理 HTTP 请求,将请求体数据转换为对象,并调用 Service 层执行业务逻辑。
  • Service 层:定义业务逻辑接口,由 ServiceImpl 实现实际的业务处理。
  • ServiceImpl 层:通过调用 Mapper 层来执行数据库操作,实现具体的业务逻辑。
    Mapper 层:负责执行数据库操作,查询和保存数据。
  • DTO:封装请求数据,使得数据传输格式统一。
  • Result:用于统一 API 响应结构,便于前端处理返回数据。

通过这个结构,接口开发的逻辑清晰,每一层都各司其职,降低了代码耦合性,同时提高了代码的可读性和维护性。

调用关系

  • UserController (Controller) 调用 UserService (Service) 来处理业务逻辑。
  • UserService (Service) 是 UserServiceImpl (ServiceImpl) 的接口。
  • UserServiceImpl (ServiceImpl) 调用 UserMapper (Mapper) 进行数据库操作。
  • UserMapper (Mapper) 使用 UserDTO (DTO) 进行数据传输。
  • UserController (Controller) 返回 Result (Response) 对象,表示接口的响应结果。
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值