API接口文档使用教程

API接口文档使用教程

API接口文档

1. 文档概述

产品经理的任务

产品经理定义每个版本需要实现的具体功能和细节,通常通过撰写产品需求文档来明确需求。并且撰写API接口文档告诉前后端工程师,怎样开发才能在双方完成任务后,前后端能够完美对接。

文档目的

API接口文档旨在帮助开发人员了解如何调用和使用本系统提供的API。文档包括了接口的定义、请求与响应格式、错误处理机制等内容。

系统架构

前端:原生JS 或 Vue.js

后端:Java原生 或 SpringBoot框架

API接口文档示例

部门管理

1.1 部门列表查询

1.1.1 基本信息

请求路径:/depts

请求方式:GET

接口描述:该接口用于部门列表数据查询

1.1.2 请求参数

1.1.3 响应数据

参数格式:application/json

参数说明:

参数名

类型

是否必须

备注

code

number

必须

响应码,1 代表成功,0 代表失败

msg

string

非必须

提示信息

data

object[ ]

非必须

返回的数据

\

- id

number

非必须

\

- name

string

非必须

\

- createTime

string

非必须

\

- updateTime

string

非必须

响应数据样例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

{

"code": 1,

"msg": "success",

"data": [

{

"id": 1,

"name": "学工部",

"createTime": "2022-09-01T23:06:29",

"updateTime": "2022-09-01T23:06:29"

},

{

"id": 2,

"name": "教研部",

"createTime": "2022-09-01T23:06:29",

"updateTime": "2022-09-01T23:06:29"

}

]

}

2. 前端使用说明

前端框架选择

1. JS原生代码(使用fetch)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

fetch('/depts', {

method: 'GET',

headers: {

'Content-Type': 'application/json',

}

})

.then(response => response.json())

.then(data => {

if (data.code === 1) {

console.log("部门列表:", data.data);

} else {

console.log("请求失败:", data.msg);

}

})

.catch(error => {

console.error('Error:', error);

});

Vue.js

在Vue组件中,可以使用Axios来简化API调用。

示例代码(使用Axios发送GET请求):

错误处理

前端应对API请求中的常见错误进行处理,如404(未找到),500(服务器错误)等。

错误处理示例:

1

2

3

4

5

6

7

8

9

10

fetch('https://api.example.com/data')

.then(response => {

if (!response.ok) {

throw new Error(`HTTP error! status: ${response.status}`);

}

return response.json();

})

.catch(error => {

console.error('API call failed:', error);

});

3. 后端实现说明

后端语言/框架选择

Java原生

使用Java原生编写API接口,通常通过HttpServlet处理请求。

示例代码(Java原生实现GET请求):

1

2

3

4

5

6

7

8

9

10

11

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

public class DataServlet extends HttpServlet {

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

response.setContentType("application/json");

PrintWriter out = response.getWriter();

out.println("{\"message\":\"Hello, World!\"}");

}

}

SpringBoot

使用SpringBoot框架,MySQL数据库,Mybatis框架来实现后端数据的提供

示例代码(SpringBoot实现前端Get的请求):

内容是查询所有部门,要求这里是Get请求,可以使用@GetMapping

使用三层架构,DeptController,DeptService,DeptMapper,响应,处理数据,调取数据

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

//日志输出的注解

@Slf4j

//controller层必带的注解

@RestController

@RequestMapping("/dept")

public class DeptController {

Dept dp=new Dept();

//依赖注入

@Autowired

private DeptService deptService;

@GetMapping()

public Result list(){

log.info("查询所有部门数据");

List depts= deptService.list();

return Result.success(depts);

}

}

这是DeptController的代码有@RequestMapping("/dept")后可以在后面定义类似GetMapping("/dept")时直接省略前面的/dept

Result类可以以统一格式把数据上传到前端,并且是JSON格式(这是个工具类,直接导入pojo包下即可)

统一返回格式大致如下

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

package com.test.springbootproject01.pojo;

import lombok.AllArgsConstructor;

import lombok.Data;

import lombok.NoArgsConstructor;

@Data

@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);

}

}

Service层用来处理数据,需要用到注解@Service

1

2

3

4

5

6

7

8

9

@Service

public class DeptServiceImpl implements DeptService {

@Autowired

private DeptMapper deptMapper;

public List list(){

List deptList = deptMapper.list();

return deptList;

}

}

最后到Mapper层用来和数据库对接,Mapper可以用XML来和数据库对接,也可以使用注解的方式,这里演示Mapper层配合xml格式调用数据

1

2

3

4

@Mapper

public interface DeptMapper {

public List list();

}

xml文件如下

1

2

3

这样Get请求从前端发送过来后,由后端Controller层接受请求,然后调用service层处理数据,然后service层再调用mapper层获取数据,最终处理完数据后返回给前端

安全性与认证

API接口使用JWT(JSON Web Token)进行认证,确保请求的安全性。如果登录成功就获得一个令牌,每次访问网站都会检查jwt令牌是否有效,同时可以给jwt令牌设置有效时限。

JWT认证示例(Spring Security集成JWT):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;

import org.springframework.security.core.context.SecurityContextHolder;

public class JwtTokenFilter extends OncePerRequestFilter {

@Override

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {

String token = request.getHeader("Authorization");

if (token != null && token.startsWith("Bearer ")) {

// Validate and parse JWT token here

UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(user, null, authorities);

SecurityContextHolder.getContext().setAuthentication(authentication);

}

chain.doFilter(request, response);

}

}

SpringBoot手搓jwt令牌认证

在使用前要在pom.xml中引入依赖

1

2

3

4

5

io.jsonwebtoken

jjwt

0.9.1

这是jwt令牌的工具类直接CV到pojo包下即可,key是秘钥,Time是令牌有效期,过期自动登出网站

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

package com.test.springbootproject01.pojo;

import io.jsonwebtoken.Claims;

import io.jsonwebtoken.Jwts;

import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;

public class JwtHelper {

private String key = "Lucius";

private Integer Time=3600*1000;

public String getJwt(Claims claims){

String jwt= Jwts.builder()

.setClaims(claims)

.signWith(SignatureAlgorithm.HS256,key)

.setExpiration(new Date(System.currentTimeMillis()+Time))

.compact();

return jwt;

}

public Claims parseJwt(String jwt){

Claims claims=Jwts.parser()

//输入秘钥

.setSigningKey(key)

//给jwt令牌解码

.parseClaimsJws(jwt)

//获取claims对象

.getBody();

return claims;

}

}

为了让没有jwt令牌的用户无法访问网站,我们得使用拦截器,下面是springboot中的拦截器

我们要先配置这个拦截器

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

package com.test.springbootproject01.interceptor;

import com.alibaba.fastjson.JSONObject;

import com.test.springbootproject01.pojo.JwtHelper;

import com.test.springbootproject01.pojo.Result;

import jakarta.servlet.http.HttpServletRequest;

import jakarta.servlet.http.HttpServletResponse;

import lombok.extern.slf4j.Slf4j;

import org.springframework.stereotype.Component;

import org.springframework.web.servlet.HandlerInterceptor;

import org.springframework.web.servlet.ModelAndView;

@Component

@Slf4j

public class LoginCheckInterceptor implements HandlerInterceptor {

@Override//目标方法运行前执行

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

//1获取请求路径

String url = request.getRequestURI();

log.info("拦截到请求:{}",url);

//如果是登录请求,放行

if(url.equals("/login")){

log.info("登录放行");

return true;

}

//2判断是否登录

String jwt=request.getHeader("token");

if(jwt==null){

log.info("未登录,拦截");

Result error=Result.error("NOT_LOGIN");

String notlogin= JSONObject.toJSONString(error);

response.getWriter().write(notlogin);

//返回false不放行

return false;

}

JwtHelper jwtHelper=new JwtHelper();

//3判断jwt是否合法

//解析jwt令牌时,如果解析失败,抛出异常,捕获异常,返回错误信息,如果解析成功,就可以放行

try {

jwtHelper.parseJwt(jwt);

} catch (Exception e) {

log.info("jwt无效");

Result error=Result.error("NOT_LOGIN");

String notlogin=JSONObject.toJSONString(error);

response.getWriter().write(notlogin);

return false;

}

log.info("jwt有效");

return true;

}

@Override

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

}

@Override

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

}

}

正常写的话需要实现HandlerInterceptor接口中的preHandle方法,这个方法是在调用controller方法前执行的,在后端未向前端发送数据时拦截检查jwt令牌,jwt令牌的逻辑请看注释

写一个类名为WebConfig,然后配置拦截器的信息

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

package com.test.springbootproject01.config;

import com.test.springbootproject01.interceptor.LoginCheckInterceptor;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.servlet.config.annotation.InterceptorRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration//@Configuration注解表示当前类是一个配置类

public class WebConfig implements WebMvcConfigurer {

@Autowired

//注入拦截器对象

private LoginCheckInterceptor loginCheckInterceptor;

@Override

//注册/添加拦截器

public void addInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(loginCheckInterceptor)

//添加拦截器拦截路径

.addPathPatterns("/**")

//除了/login以外的路径都要被拦截

.excludePathPatterns("/login");

}

}

然后回到登录的controller层

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

package com.test.springbootproject01.Controller;

import com.test.springbootproject01.Service.EmpService;

import com.test.springbootproject01.pojo.Emp;

import com.test.springbootproject01.pojo.JwtHelper;

import com.test.springbootproject01.pojo.Result;

import io.jsonwebtoken.Claims;

import io.jsonwebtoken.impl.DefaultClaims;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.PostMapping;

import org.springframework.web.bind.annotation.RequestBody;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

@Slf4j

@RestController

@RequestMapping("/login")

public class LoginController {

@Autowired

private EmpService empService;

@PostMapping

public Result Login(@RequestBody Emp emp){

log.info("{}请求登录",emp);

Emp emp1=empService.login(emp);

//如果查有此人就开始准备制作令牌

if(emp1!=null){

JwtHelper jh=new JwtHelper();

Claims claims=new DefaultClaims();

claims.put("id",emp1.getId());

claims.put("username",emp1.getUsername());

claims.put("password",emp1.getPassword());

log.info("请求人用户名:{}",emp.getUsername());

log.info("请求人密码{}",emp.getPassword());

String jwt=jh.getJwt(claims);

return Result.success(jwt);

}

return Result.error("NOT_LOGIN");

}

}

java代码是这样的(