【API Echo】API测试回调工具 - 回显请求内容

API Echo 服务

项目简介

API Echo 是一个轻量级的API测试工具服务,用于测试HTTP请求和响应。该服务可以回显请求内容,帮助开发人员调试和测试API接口。

作者 : Johnny
创建时间 : 2022年7月5日
版本: v1

技术栈

  • 后端框架: Flask 2.1.2
  • 开发语言: Python 3.x
  • 运行端口: 9999
  • 监听地址: 0.0.0.0(支持外部访问)

核心功能

1. 主要特性

  • ✅ 支持多种HTTP方法(GET、POST、PUT、DELETE)
  • ✅ 请求内容回显(headers、body)
  • ✅ 灵活的响应配置
  • ✅ 布尔值和数字状态码返回
  • ✅ Web界面访问
  • ✅ 请求时间记录
  • ✅ JSON格式支持

2. 业务实现

2.1 请求回显服务

核心功能是将接收到的HTTP请求信息进行记录和回显,包括:

  • 请求方法(GET/POST/PUT/DELETE)
  • 请求URL
  • 请求头(Headers)
  • 请求体(Body)
  • 请求时间(UTC时间)
2.2 响应内容定制
  • 自定义键值对返回
  • 布尔值返回控制
  • 状态码数字返回
  • JSON格式响应

API接口文档

基础信息

  • Base URL : http://localhost:9999
  • 响应格式: JSON

接口列表

接口名称 请求方法 接口路径 说明
主页 GET / 返回API文档页面
接收消息 POST/GET/PUT/DELETE /apiecho/v1/sync 请求内容回显
设置返回值 POST/GET/PUT/DELETE /apiecho/v1/config/<key>/<value> 自定义键值对返回
返回布尔值 POST/GET/PUT/DELETE /apiecho/v1/bool/<key>/<value> 返回布尔值(true/false)
返回状态码 POST/GET/PUT/DELETE /apiecho/v1/code/<code>/<num> 返回自定义状态码
GET方法 GET /apiecho/v1/get 标准GET请求测试
POST方法 POST /apiecho/v1/post 标准POST请求测试
PUT方法 PUT /apiecho/v1/put 标准PUT请求测试
DELETE方法 DELETE /apiecho/v1/delete 标准DELETE请求测试

接口详细说明

1. /apiecho/v1/sync - 同步回显接口

功能: 回显所有接收到的请求信息

支持方法: POST, GET, PUT, DELETE

响应示例:

json 复制代码
{
  "code": 200,
  "success": true,
  "method": "POST",
  "url": "http://localhost:9999/apiecho/v1/sync",
  "time": "2026-01-15 12:00:00.123456",
  "body": {
    "test": "data"
  }
}

特殊情况:

  • 无请求体时返回: "message": "no body"
  • 非JSON格式请求体时返回: "message": "body not json"
2. /apiecho/v1/config/<key>/<value> - 配置接口

功能: 返回自定义的键值对

支持方法: POST, GET, PUT, DELETE

路径参数:

  • key: 自定义键名(字符串)
  • value: 自定义值(字符串)

请求示例:

复制代码
GET /apiecho/v1/config/status/success

响应示例:

json 复制代码
{
  "code": 200,
  "method": "GET",
  "url": "http://localhost:9999/apiecho/v1/config/status/success",
  "time": "2026-01-15 12:00:00.123456",
  "status": "success"
}
3. /apiecho/v1/bool/<key>/<value> - 布尔值接口

功能: 返回布尔类型的值

支持方法: POST, GET, PUT, DELETE

路径参数:

  • key: 键名(字符串)
  • value: 布尔值(只有"true"返回true,其他均返回false)

请求示例:

复制代码
POST /apiecho/v1/bool/isActive/true

响应示例:

json 复制代码
{
  "code": 200,
  "method": "POST",
  "url": "http://localhost:9999/apiecho/v1/bool/isActive/true",
  "time": "2026-01-15 12:00:00.123456",
  "isActive": true
}

注意事项:

  • GET和DELETE方法的body参数可选
  • POST和PUT方法建议传递body
4. /apiecho/v1/code/<code>/<num> - 状态码接口

功能: 返回自定义状态码的数字

支持方法: POST, GET, PUT, DELETE

路径参数:

  • code: 键名(字符串)
  • num: 数字值(必须是整数)

请求示例:

复制代码
GET /apiecho/v1/code/status/200

响应示例:

json 复制代码
{
  "success": true,
  "method": "GET",
  "url": "http://localhost:9999/apiecho/v1/code/status/200",
  "time": "2026-01-15 12:00:00.123456",
  "status": 200
}

错误响应(非数字值):

json 复制代码
{
  "message": "Please input number",
  "success": false
}
5. /apiecho/v1/get - GET测试接口

功能: 标准GET请求测试

支持方法: GET

响应示例:

json 复制代码
{
  "code": 200,
  "Success": true,
  "method": "GET",
  "data": {
    "author": "hw",
    "desc": "This Api for TEST!"
  },
  "time": "2026-01-15 12:00:00.123456"
}
6. /apiecho/v1/post - POST测试接口

功能: 标准POST请求测试(必须传递body)

支持方法: POST

请求要求: 必须包含JSON格式的请求体

响应示例:

json 复制代码
{
  "code": 200,
  "Success": true,
  "method": "POST",
  "url": "http://localhost:9999/apiecho/v1/post",
  "time": "2026-01-15 12:00:00.123456",
  "body": {
    "test": "data"
  }
}

错误响应(无body):

json 复制代码
{
  "code": 404,
  "Success": false,
  "message": "Please send body"
}
7. /apiecho/v1/put - PUT测试接口

功能: 标准PUT请求测试(必须传递body)

支持方法: PUT

行为与POST接口一致

8. /apiecho/v1/delete - DELETE测试接口

功能: 标准DELETE请求测试

支持方法: DELETE

响应示例:

json 复制代码
{
  "code": 200,
  "Success": true,
  "method": "DELETE",
  "data": {
    "author": "hw",
    "desc": "This Api for TEST!"
  },
  "time": "2026-01-15 12:00:00.123456"
}

项目结构

复制代码
apiecho/
├── app.py              # Flask应用主文件,包含所有API端点
├── apiecho.html        # API文档展示页面(Web界面)
├── requirements.txt    # Python依赖包列表
├── run.sh             # Linux/Mac启动脚本
└── README.md          # 项目文档(本文件)

源码

app.py源码

python 复制代码
#!/usr/bin/env python
# coding=utf-8
__author__ = "Johnny"
__date__ = "2022/7/5 "
__description__ = "api request and response echo"

import json
import logging

from datetime import datetime

import flask
from flask import request, render_template, send_from_directory

app = flask.Flask(__name__)
logger = logging.Logger(__name__)


@app.route("/")
def as_home():
    return send_from_directory('', 'apiecho.html')


@app.route("/apiecho/v1/sync", methods=["POST", "GET", "PUT", "DELETE"])
def ae_sync():
    response = {'code': 200, 'success': True, 'method': request.method, "url": request.url,
                'time': str(datetime.utcnow())}

    print(("\n---------------------      /apiecho/v1/sync       ------------------------\n"))
    print("TIME: ", str(datetime.now()))
    print("Method: ", request.method)
    # logger.info(request.method)
    print("Headers: \n\n", request.headers)

    if not request.content_length:
        response['message'] = "no body"
    else:
        try:
            print("Body: \n\n", json.loads(request.data))
            response['body'] = json.loads(request.data)
        except:
            print("Body: \n\n", request.data)
            response['message'] = "body not json"

    print("\nReturn Response:\n", response)
    return response


@app.route("/apiecho/v1/config/<key>/<value>", methods=["POST", "GET", "PUT", "DELETE"])
def ae_config(key, value):
    response = {'code': 200, 'method': request.method, "url": request.url, 'time': str(datetime.utcnow())}

    print(("\n---------------------      /apiecho/v1/config       ------------------------\n"))

    print("TIME: ", str(datetime.now()))
    print("Method: ", request.method)
    print("Headers: \n\n", request.headers)

    if value:
        response[key] = str(value)
    else:
        response['message'] = "no value"

    if not request.content_length:
        response['message'] = "no body"
    else:
        try:
            print("Body: \n\n", json.loads(request.data))
            response['body'] = json.loads(request.data)
        except:
            print("Body: \n\n", request.data)
            response['message'] = "body not json"

    print("\nReturn Response: \n", response)
    return response


@app.route("/apiecho/v1/bool/<key>/<value>", methods=["POST", "GET", "PUT", "DELETE"])
def ae_bool(key, value):
    """
    GET DELETE body选传
    POST PUT 必须传body
    :param key:
    :param value:
    :return:
    """

    response = {'code': 200, 'method': request.method, "url": request.url, 'time': str(datetime.utcnow())}
    print(("\n---------------------      /apiecho/v1/bool       ------------------------\n"))

    print("TIME: ", str(datetime.now()))
    print("Method: ", request.method)
    print("Headers: \n\n", request.headers)
    try:
        if str(value) == 'true':
            response[key] = True
        else:
            response[key] = False
    except:
        response['message'] = "value must send"
        response['code'] = 404
        return response

    if not request.content_length:
        response['message'] = "no body"
    else:
        try:
            print("Body: \n\n", json.loads(request.data))
            response['body'] = json.loads(request.data)
        except:
            print("Body: \n\n", request.data)
            response['message'] = "body not json"

    print("\nReturn Response: \n", response)
    return response


@app.route("/apiecho/v1/code/<code>/<num>", methods=["POST", "GET", "PUT", "DELETE"])
def ae_code(code, num):
    """
    GET DELETE body选传
    POST PUT 必须传body
    :param code:
    :param num:
    :return:
    """
    response = {'success': True, 'method': request.method, 'url': request.url, 'time': str(datetime.utcnow())}

    print(("\n---------------------     /apiecho/v1/code       ------------------------\n"))

    print("TIME: ", str(datetime.now()))
    print("Method: ", request.method)
    print("Headers: \n\n", request.headers)

    try:
        response[code] = int(num)
    except ValueError:
        response['message'] = "Please input number"
        response['success'] = False
        return response

    if not request.content_length:
        response['message'] = "no body"
    else:
        try:
            print("Body: \n\n", json.loads(request.data))
            response['body'] = json.loads(request.data)
        except:
            print("Body: \n\n", request.data)
            response['message'] = "body not json"

    print("\nReturn Response: \n", response)
    return response


@app.route("/apiecho/v1/get", methods=["GET"])
def ae_get():
    response = {'code': 200, 'Success': True, 'method': request.method,
                'data': {"author": "hw", "desc": "This Api for TEST!"}, 'time': str(datetime.utcnow())}

    print(("\n---------------------     /apiecho/v1/get       ------------------------\n"))

    if not request.content_length:
        response['message'] = "no body"
    else:
        try:
            print("Body: \n\n", json.loads(request.data))
            response['body'] = json.loads(request.data)
        except:
            print("Body: \n\n", request.data)
            response['message'] = "body not json"
    print("\nReturn Response: \n", response)

    return response


@app.route("/apiecho/v1/post", methods=["POST"])
def ae_post():
    response = {'code': 200, 'Success': True, 'method': request.method, "url": request.url,
                'time': str(datetime.utcnow())}

    print(("\n---------------------     /apiecho/v1/post       ------------------------\n"))

    try:
        if request.data:
            print("Body: \n\n", json.loads(request.data))
            response['body'] = json.loads(request.data)
        elif request.json:
            print("Body: \n\n", request.json)
            response['body'] = json.loads(request.json)
    except:
        return {'code': 404, 'Success': False, "message": "Please send body"}

    print("\nReturn Response: \n", response)

    return response


@app.route("/apiecho/v1/put", methods=["PUT"])
def ae_put():
    response = {'code': 200, 'Success': True, 'method': request.method, "url": request.url,
                'time': str(datetime.utcnow())}

    print(("\n---------------------     /apiecho/v1/put       ------------------------\n"))

    try:
        if request.data:
            print("Body: \n\n", json.loads(request.data))
            response['body'] = json.loads(request.data)
        elif request.json:
            print("Body: \n\n", request.json)
            response['body'] = json.loads(request.json)
    except:
        return {'code': 404, 'Success': False, "message": "Please send body"}

    print("\nReturn Response: \n", response)

    return response


@app.route("/apiecho/v1/delete", methods=["DELETE"])
def ae_delete():
    response = {'code': 200, 'Success': True, 'method': request.method,
                'data': {"author": "hw", "desc": "This Api for TEST!"}, 'time': str(datetime.utcnow())}

    print(("\n---------------------     /apiecho/v1/delete       ------------------------\n"))

    if not request.content_length:
        response['message'] = "no body"
    else:
        try:
            print("Body: \n\n", json.loads(request.data))
            response['body'] = json.loads(request.data)
        except:
            print("Body: \n\n", request.data)
            response['message'] = "body not json"
    print("\nReturn Response: \n", response)
    return response


app.run(host="0.0.0.0", port=9999)

安装与运行

环境要求

  • Python 3.6+
  • pip包管理器

安装步骤

  1. 克隆或下载项目
bash 复制代码
cd apiecho
  1. 安装依赖包
bash 复制代码
pip install -r requirements.txt

运行方式

方式一:使用Python直接运行
bash 复制代码
python app.py
方式二:使用启动脚本(Linux/Mac)
bash 复制代码
chmod +x run.sh
./run.sh
方式三:Windows PowerShell
powershell 复制代码
python -u app.py

访问服务

服务启动后,可通过以下方式访问:

使用示例

cURL示例

1. 测试同步回显

bash 复制代码
curl -X POST http://localhost:9999/apiecho/v1/sync \
  -H "Content-Type: application/json" \
  -d '{"name": "test", "value": 123}'

2. 配置返回值

bash 复制代码
curl -X GET http://localhost:9999/apiecho/v1/config/status/ok

3. 获取布尔值

bash 复制代码
curl -X POST http://localhost:9999/apiecho/v1/bool/isEnabled/true \
  -H "Content-Type: application/json" \
  -d '{"userId": 1}'

4. 设置状态码

bash 复制代码
curl -X GET http://localhost:9999/apiecho/v1/code/httpStatus/404

Python requests示例

python 复制代码
import requests
import json

# 1. POST请求测试
url = "http://localhost:9999/apiecho/v1/sync"
payload = {"username": "test", "password": "123456"}
headers = {"Content-Type": "application/json"}

response = requests.post(url, json=payload, headers=headers)
print(response.json())

# 2. 配置接口测试
response = requests.get("http://localhost:9999/apiecho/v1/config/result/success")
print(response.json())

# 3. 布尔值测试
response = requests.post("http://localhost:9999/apiecho/v1/bool/isActive/true")
print(response.json())

JavaScript fetch示例

javascript 复制代码
// POST请求示例
fetch('http://localhost:9999/apiecho/v1/sync', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'test',
    value: 123
  })
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

设计特点

1. 架构设计

  • 单体应用: 采用Flask轻量级框架,所有功能集中在一个文件中
  • RESTful风格: API设计遵循REST规范
  • 无状态服务: 每个请求独立处理,不依赖服务器状态

2. 日志与调试

服务在控制台输出详细的请求信息,便于调试:

  • 请求时间
  • HTTP方法
  • 请求头信息
  • 请求体内容
  • 返回响应

控制台输出示例:

复制代码
---------------------      /apiecho/v1/sync       ------------------------

TIME:  2026-01-15 12:00:00.123456
Method:  POST
Headers: 

Host: localhost:9999
Content-Type: application/json
...

Body: 

{'name': 'test', 'value': 123}

Return Response:
 {'code': 200, 'success': True, 'method': 'POST', 'url': '...', 'time': '...', 'body': {'name': 'test', 'value': 123}}

3. 错误处理

  • JSON解析异常处理
  • 数字类型转换校验
  • 请求体缺失提示
  • 友好的错误消息返回

4. 扩展性

  • 易于添加新的API端点
  • 响应格式统一,便于前端集成
  • 支持多种HTTP方法

应用场景

  1. API接口测试: 快速验证API调用是否正确
  2. Webhook调试: 接收并查看webhook推送的数据
  3. 客户端开发: 在后端API未完成时进行前端开发
  4. 接口文档演示: 提供实时的API调用示例
  5. 网络请求调试: 检查HTTP请求的headers和body
  6. 自动化测试: 作为测试环境的Mock服务

依赖包说明

包名 版本 用途
Flask 2.1.2 Web框架
click 8.1.3 命令行工具(Flask依赖)
Jinja2 3.1.2 模板引擎(Flask依赖)
Werkzeug 2.1.2 WSGI工具库(Flask依赖)
itsdangerous 2.1.2 数据签名(Flask依赖)
MarkupSafe 2.1.1 字符串转义(Jinja2依赖)

注意事项

  1. 生产环境使用: 本服务仅供开发测试使用,不建议在生产环境部署
  2. 安全性: 服务监听在0.0.0.0,外网可访问,注意防火墙配置
  3. 端口占用: 默认使用9999端口,确保端口未被占用
  4. JSON格式: 大部分接口期望接收JSON格式的请求体
  5. 时间格式: 返回的时间为UTC时间,非本地时间

常见问题

Q1: 服务启动后无法访问?

A: 检查防火墙设置,确保9999端口已开放。Windows用户可能需要允许Python通过防火墙。

Q2: POST请求返回"Please send body"错误?

A: POST和PUT接口必须携带请求体,且Content-Type应设置为application/json。

Q3: 如何修改服务端口?

A : 编辑app.py最后一行,将port=9999修改为其他端口号。

Q4: 接口返回"body not json"?

A: 请求体内容不是有效的JSON格式,请检查请求体格式是否正确。

Q5: 如何查看请求详情?

A: 查看运行服务的控制台窗口,所有请求信息都会实时打印。

更新日志

  • v1.0 (2022-07-05): 初始版本发布
    • 实现基础的API回显功能
    • 支持多种HTTP方法
    • 提供Web文档界面
    • 添加配置、布尔值、状态码等灵活接口

许可证 MIT License

本项目仅供学习和测试使用。

联系方式

作者 : Johnny
创建日期: 2022年7月5日


Generated by API Echo Service - A Simple API Testing Tool


相关推荐
知乎的哥廷根数学学派1 小时前
基于物理约束指数退化与Hertz接触理论的滚动轴承智能退化趋势分析(Pytorch)
开发语言·人工智能·pytorch·python·深度学习·算法·机器学习
Ethan Hunt丶1 小时前
基于Pytorch预训练模型实现声纹识别系统
人工智能·pytorch·python·语音识别
Katecat996632 小时前
【铁路检测】YOLO11-C3k2-StripCGLU模型在铁路轨道缺陷检测中的应用与改进
python
理想是做全栈工程师2 小时前
基于UNet的带噪黑白数字图像分割模型
人工智能·pytorch·python·anaconda
lbb 小魔仙2 小时前
从零搭建 Spring Cloud 微服务项目:注册中心 + 网关 + 配置中心全流程
java·python·spring cloud·微服务
霖雨2 小时前
备份 SQL Server 到 Azure Storage
后端·python·microsoft·flask·azure
tjjucheng2 小时前
小程序定制开发哪家有团队支持
python
我送炭你添花2 小时前
Pelco KBD300A 模拟器:08.模板库 + 一键场景加载
运维·开发语言·python·自动化