当前位置: 首页 > article >正文

HTTP 和RESTful API 基础,答疑

 

一文搞懂RESTful API - bigsai - 博客园


1. API 路径   开头必须 /,表示绝对路径,不支持 ...(相对路径)。API 结尾 / 通常不需要,但部分框架会自动处理 / → 无 /

推荐

GET /api/v1/products    # 资源集合
GET /api/v1/products/123  # 具体资源

🚫 避免

GET ./api/v1/products    # ❌ API 不能用 `.` 开头
GET /api/v1/products/    # ❌ 可能导致 404

2. 系统路径  Linux/Windows 支持 . 开头(相对路径)。结尾 / 代表目录,不加 / 可能是文件。

/home/user/docs/    # 目录
/home/user/docs.txt # 文件

3. 关键区别

特性API 路径系统路径
相对路径❌ 不支持 ../file.txt 代表当前目录
绝对路径/api/v1/users/home/user/docs/
结尾 /🚫 通常不加✅ 代表目录

最佳实践  API 必须 / 开头,通常不加结尾 /。文件路径 目录加 /,文件不加 /


Swagger 提供了一套完整的工具集,用于设计、构建、文档化和测试 RESTful API。其核心组件包括 Swagger Codegen 和 Swagger UI。Swagger Codegen 生成的是代码框架(客户端 SDK 或服务端模板),需要开发者补充逻辑才能运行。Swagger UI 生成的是交互式文档网页,用于展示和测试 API,不涉及代码生成。

1. Swagger Codegen 的作用与效果

功能:根据 OpenAPI 规范(YAML/JSON 格式的 API 描述文件),自动生成客户端 SDK(如 Java、Python 的调用库)和服务器端框架代码(如 Spring Boot、Flask 的接口实现模板)。

生成内容

  • 代码文件:例如生成 Java 的模型类、接口定义、HTTP 请求工具类,或 Python 的 Flask 路由代码等。这些文件需要开发者进一步补充业务逻辑才能运行。
  • 支持框架:生成的代码适配多种框架(如 Spring Boot、Django、Express),但并非“完整的应用程序”,而是提供基础代码框架,开发者需自行完善。

使用场景:假设你有一个 OpenAPI 文件,通过 Swagger Codegen 可以快速生成客户端调用库(供其他服务使用你的 API)或服务端接口模板(简化开发流程)。


2. Swagger UI 的作用与效果

功能:将 OpenAPI 规范文件转换为交互式文档网页,允许用户直接在浏览器中查看 API 端点、参数说明,并实时发送请求测试接口。

生成内容

  • 可视化界面:以 HTML/CSS/JS 渲染的网页,展示 API 的路径、请求方法、参数、响应示例等。用户可填写参数并点击“Try it out”测试接口。

  • 实时反馈:显示请求的响应结果(如 JSON 数据)、状态码及错误信息,帮助开发者和测试人员快速验证 API 功能。

使用场景:在开发阶段,后端团队通过 Swagger UI 提供文档给前端或测试团队,减少沟通成本;部署后,作为 API 的官方文档供外部调用者参考。


3. OpenAPI 规范文件的实际形态

文件格式:通常是 YAML 或 JSON 文件,例如 openapi.yamlswagger.json,定义了 API 的元数据(如标题、版本)、端点路径、请求方法、参数类型、响应格式及错误码等。例如:

openapi: 3.0.0
info:
  title: 示例API
  version: 1.0.0
paths:
  /users:
    get:
      summary: 获取用户列表
      parameters:
        - name: limit
          in: query
          schema:
            type: integer
      responses:
        '200':
          description: 成功返回用户列表

Swagger UI 的界面示例
访问方式:启动服务后,通过 URL(如 http://localhost:8080/swagger-ui.html)打开页面。

界面元素API 列表:左侧展示所有接口路径(如 /users/orders)。参数输入框:支持填写路径参数、查询参数、请求体(JSON 格式)。测试按钮:点击“Try it out”发送请求,页面下方显示服务器响应结果。示例值:自动生成请求和响应的示例数据,帮助理解接口用法。


4. RESTful API 框架分类

Java 生态Spring Boot:最流行的 Java 框架,内置 Tomcat,支持快速构建 REST API。JAX-RS:Java 标准(如 Jersey、RESTEasy),基于注解开发。

Python 生态Django REST Framework:基于 Django,适合复杂业务和权限控制。Flask:轻量级,通过扩展(如 Flask-RESTful)支持 REST。FastAPI:高性能,支持异步和自动生成 Swagger 文档。

5. 跨语言项目的可行性

可以同时使用 Java 和 Python 框架,但需要通过 API 通信或消息队列解耦。例如:Java 主系统:处理核心业务(如医院管理系统的患者数据)Python 子服务:调用 LLM(如 GPT-3)生成 SQL,通过 HTTP API 返回结果给 Java 系统。

技术实现Java 后端调用 Python 服务的 API(如 FastAPI 暴露的 /generate-sql 端点)。数据格式统一(如 JSON),确保跨语言解析兼容。使用 API 网关(如 Spring Cloud Gateway)统一管理请求路由。


 FastAPI、Postman、Flask 的关系 

  • FastAPI 和 Flask:两者都是 Python 的 Web 框架,用于构建 API。FastAPI 的性能优于 Flask,适合大规模并发应用。Flask 适合简单的 Web 应用。
    • FastAPI:基于 ASGI(异步服务器网关接口),支持异步编程和高性能,内置数据验证(Pydantic)、自动文档生成(Swagger/ReDoc)。Flask:基于 WSGI(同步接口),轻量级但需手动处理数据验证和文档生成。
    • 兼容性:FastAPI 与异步数据库(如 asyncpg)更适配,Flask 适合搭配传统同步库(如 SQLAlchemy)。
    • Postman:独立于框架的 API 测试工具,用于调试和验证 FastAPI/Flask 开发的接口。

示例代码(FastAPI vs Flask)

# FastAPI 示例(异步)
from fastapi import FastAPI

app = FastAPI()

@app.get("/items/{item_id}")
async def read_item(item_id: int):
    return {"item_id": item_id}

# 运行: uvicorn filename:app --reload
# Flask 示例(同步)
from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/items/<int:item_id>', methods=['GET'])
def get_item(item_id):
    return jsonify({"item_id": item_id})

# 运行: python filename.py
if __name__ == '__main__':
    app.run(debug=True)

RESTful API 里没有方法定义,我如何判断它是增删改查?

RESTful API 通过 HTTP 方法 来区分操作,而不是通过 URL。例如:

方法

作用

示例 URL

GET

获取数据

GET /users/1

POST

创建数据

POST /users

PUT

更新数据

PUT /users/1

DELETE

删除数据

DELETE /users/1

如果 URL 里没有明确的增删改查,通常需要看 HTTP 方法(GET、POST、PUT、DELETE)来判断它的作用。

API 是不是就等于链接?

不完全正确。API(应用程序接口)可以包含但不等同于 URL,API 指的是一组规则和协议,不仅限于 HTTP,还可以是数据库 API、操作系统 API、函数库 API 等。API ≠ 网址,但 Web API 确实会以 URL 的形式暴露出来。

Web API:
GET https://api.example.com/users/1

数据库 API(Java 代码):
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password");

操作系统 API(调用 Windows API):
#include <windows.h>
MessageBox(0, "Hello", "Message Box", MB_OK);

    ####  应用层是客户端和服务器端都有的:

    1. 应用层的定义

    应用层是网络体系结构中的最高层,直接面向用户和应用程序,它负责处理高层协议,常见的应用层协议包括HTTP、FTP、SMTP、DNS等。客户端和服务器端的应用层,职责和运行环境不同。客户端应用层主要处理用户输入和界面呈现,而服务器端应用层主要处理业务逻辑和数据存储。两者通过网络协议(如HTTP)进行通信

    • 客户端应用层: 运行在用户设备上的应用程序或进程,如Web浏览器、电子邮件客户端等。发送请求,并处理响应。例如,用户在浏览器中输入网址,浏览器作为客户端应用层,会向目标Web服务器发送HTTP请求,获取网页内容并呈现给用户。

    • 服务器端应用层: 运行在服务器上的应用程序或服务,如Web服务器、邮件服务器等。接收并处理来自客户端的请求,返回相应的数据或服务。例如,Web服务器接收到浏览器的HTTP请求后,会处理该请求并返回相应的网页内容。

    3. 应用层在客户端和服务器端的交互示例

    以下是一个简单的HTTP请求-响应过程:

    1. 客户端(浏览器)发送HTTP请求:

      GET /index.html HTTP/1.1
      Host: www.example.com
      
    2. 服务器(Web服务器)接收请求并返回响应:

      HTTP/1.1 200 OK
      Content-Type: text/html
      
      <html>
      <head><title>Example Page</title></head>
      <body>
          <h1>Welcome to Example.com!</h1>
      </body>
      </html>
      

    **前端框架主要是针对于客户端而言的概念**

    前端框架(如React、Vue)是用于构建用户界面的JavaScript框架,运行在客户端(浏览器)中。这些框架帮助开发者创建动态、交互式的网页应用。虽然服务器端也可以使用类似的框架(如Next.js、Nuxt.js)进行服务端渲染,但传统意义上的前端框架主要存在于客户端,用于处理用户界面和交互。

    #### 缓存

    缓存机制在应用层,而应用层是客户端服务器端都有的

    • 客户端缓存:客户端应用程序可以在本地存储数据,以减少对服务器的请求次数,提高响应速度。例如,浏览器会缓存静态资源(如HTML、CSS、JavaScript文件),以加快页面加载速度。

    • 服务器端缓存:服务器可以在内存中存储经常访问的数据或计算结果,以减少对底层数据库的访问,提高处理效率。例如,使用内存对象缓存(如Memcached,数据库缓存使用 Redis)来存储热点数据。

    1. 浏览器缓存(HTTP 缓存)

    示例:使用 Cache-ControlETag 实现缓存控制 服务器端(Node.js 示例):

    const http = require('http');
    const crypto = require('crypto');
    
    // 模拟的资源数据
    const resourceData = 'Hello, this is the resource content.';
    
    // 计算资源的 ETag(可以使用资源内容的哈希值)
    const etag = crypto.createHash('md5').update(resourceData).digest('hex');
    
    const server = http.createServer((req, res) => {
      if (req.url === '/resource') {
        const ifNoneMatch = req.headers['if-none-match'];
    
        // 检查请求头中的 If-None-Match 是否与服务器的 ETag 匹配
        if (ifNoneMatch === etag) {
          // ETag 匹配,资源未修改,返回 304 Not Modified
          res.writeHead(304, {
            'Cache-Control': 'public, max-age=3600', // 缓存时间为 1 小时
            'ETag': etag,
          });
          res.end();
        } else {
          // ETag 不匹配,资源已修改,返回新的资源和 ETag
          res.writeHead(200, {
            'Content-Type': 'text/plain',
            'Cache-Control': 'public, max-age=3600',
            'ETag': etag,
          });
          res.end(resourceData);
        }
      } else {
        res.writeHead(404, { 'Content-Type': 'text/plain' });
        res.end('Not Found');
      }
    });
    
    server.listen(3000, () => {
      console.log('Server running at http://localhost:3000/');
    });
    

    客户端(浏览器请求):

    // 使用 Fetch API 请求资源
    fetch('http://localhost:3000/resource')
      .then((response) => {
        if (response.status === 200) {
          // 资源已更新,处理新的资源内容
          return response.text().then((data) => {
            console.log('Resource data:', data);
          });
        } else if (response.status === 304) {
          // 资源未修改,使用缓存中的数据
          console.log('Resource not modified. Using cached version.');
        }
      })
      .catch((error) => {
        console.error('Error fetching resource:', error);
      });
    

    流程图解:

    1. 首次请求:客户端请求 http://localhost:3000/resource。服务器返回资源内容,状态码 200,并包含 Cache-ControlETag 头。

      HTTP/1.1 200 OK
      Content-Type: text/plain
      Cache-Control: public, max-age=3600
      ETag: "5d41402abc4b2a76b9719d911017c592"
      
      Hello, this is the resource content.
      
    2. 后续请求(在缓存有效期内):客户端再次请求相同资源,并在请求头中包含 If-None-Match。服务器检查 If-None-Match,发现资源未修改,返回 304 状态码,无需传输资源内容。客户端接收到 304 响应后,从缓存中读取并使用资源内容。

    3. GET /resource HTTP/1.1
      Host: localhost:3000
      If-None-Match: "5d41402abc4b2a76b9719d911017c592"
      
        HTTP/1.1 304 Not Modified
        Cache-Control: public, max-age=3600
        ETag: "5d41402abc4b2a76b9719d911017c592"
        

      2. 应用层缓存示例:在 React 应用中使用 localStorage 缓存 API 响应数据

      步骤:

      1. 首次加载应用时:检查 localStorage 中是否存在缓存的新闻数据。如果存在且未过期,直接使用缓存的数据渲染界面。如果不存在或已过期,发送网络请求获取最新数据,渲染界面,并将数据缓存到 localStorage

      2. 在组件中实现:

        import React, { useEffect, useState } from 'react';
        
        const NewsComponent = () => {
          const [news, setNews] = useState([]);
          const cacheKey = 'newsData';
          const cacheExpiry = 60 * 60 * 1000; // 缓存有效期:1 小时
        
          useEffect(() => {
            const fetchNews = async () => {
              try {
                const cachedData = localStorage.getItem(cacheKey);
                if (cachedData) {
                  const { data, timestamp } = JSON.parse(cachedData);
                  if (Date.now() - timestamp < cacheExpiry) {
                    // 使用缓存的数据
                    setNews(data);
                    console.log('Using cached data');
                    return;
                  }
                }
        
                // 缓存不存在或已过期,发送网络请求
                const response = await fetch('https://api.example.com/news');
                const data = await response.json();
                setNews(data);
        
                // 将新数据缓存到 localStorage
                localStorage.setItem(
                  cacheKey,
                  JSON.stringify({ data, timestamp: Date.now() })
                );
                console.log('Fetched and cached new data');
              } catch (error) {
                console.error('Error fetching news:', error);
              }
            };
        
            fetchNews();
          }, []);
        
          return (
            <div>
              <h1>Latest News</h1>
              <ul>
                {news.map((item) => (
                  <li key={item.id}>{item.title}</li>
                ))}
              </ul>
            </div>
          );
        };
        
        export default NewsComponent;
        

      RESTful API 是改变服务器的资源,还是改变客户端的资源?

      RESTful API 主要是用来操作服务器端的资源,而客户端的状态是如何随之变化的,取决于客户端如何使用 API 提供的数据。

      • 服务器端资源的改变:通过 POST 创建新资源等等,只有 GET 不会修改服务器端数

      • 客户端状态:是指客户端的 UI、页面展示、数据缓存等。RESTful API 并不会直接管理客户端的状态,而是提供数据,让客户端自己决定如何更新其状态。例如:用户请求 GET /users/1,服务器返回用户数据,客户端用这个数据来更新页面(但服务器上的数据没有变)

      REST 设计的无状态性(Stateless)是指:服务器不会存储客户端的会话状态,每个请求都是独立的,不依赖之前的请求。客户端必须在每个请求中提供所有必要的信息,例如身份认证(Token、Session ID 等)。服务器根据请求中的信息做出响应,而不会记住上一次请求的状态。

      • 传统 Web 应用(有状态):用户登录后,服务器会在内存里保存用户会话,后续请求只需要提供一个 session_id

      • RESTful API(无状态):每次请求都必须带上 Authorization 头,服务器不会记住用户的身份,而是根据请求中的 Token 进行验证。


       #### 筛选和分页

      标准的 URL 查询参数不直接支持 OR 操作。需要看API服务器提供端究竟是怎么规定的。一种常见的解决方案是使用逗号分隔的列表表示多个值。

      GET /classes?name=def,ABC
      

      或者重复参数:

      GET /classes?name=def&name=ABC
      

      分页查询通常通过在 URL 中添加 pagesize 参数来实现,分别表示页码和每页的数据量。

      GET /classes?page=1&size=10
      

      此请求表示获取第 1 页的数据,每页包含 10 条记录。如果有多页数据,可以调整 page 参数的值来获取不同页的数据。

      GET /classes?page=2&size=10
      

      此请求表示获取第 2 页的数据,每页同样包含 10 条记录。

      某些 API 中,可能使用 offsetlimit 参数来控制分页:此请求表示从第 11 条记录开始,获取 10 条记录。

      GET /classes?offset=10&limit=10
      


      http://www.kler.cn/a/554400.html

      相关文章:

    4. Flowable + Claude Desktop:AI驱动的RPA新玩法
    5. 服务器从零部署nodejs(midway)项目
    6. vue添加当前时间
    7. fastapi sqlalchemy 日志 logging 写入异常 多进程文件写入异常
    8. 一文讲解Redis为什么读写性能高以及I/O复用相关知识点
    9. 【Python爬虫(28)】爬虫时代,数据安全的坚盾与隐私保护的密锁
    10. 电磁铁的磁芯材质
    11. Thor: 统一AI模型网关的革新之选
    12. 车载音频配置(二)
    13. 本地部署DeepSeek大模型
    14. 在前端如何把SEO优化做到极致?
    15. angular中使用animation.css实现翻转展示卡片正反两面效果
    16. centos下使用pyenv管理python版本
    17. 基于SpringBoot的乐享田园系统【附源码】
    18. D. C05.L08.贪心算法入门(一).课堂练习4.危险的实验(NHOI2015初中)
    19. 从零开始用STM32驱动DRV8301:无人机/机器人电机控制指南
    20. minio作为K8S后端存储
    21. Android看门狗(WatchDog)
    22. 缺少网络安全组织架构 网络安全缺陷
    23. 前端面试场景题 1 (批量处理toast、减少if-else)