核心概念辨析
在开始之前,我们先理清几个容易混淆的概念:

- WebService:这是一个广义的术语,指的是通过网络、基于标准协议(如 HTTP)进行的应用程序间交互的技术,它可以指代 SOAP 或 REST。
- SOAP (Simple Object Access Protocol):一个协议,它使用 XML 进行数据交换,具有严格的规范(WSDL - Web Services Description Language),SOAP 通常被认为更“重量级”,但功能强大、安全、且跨语言。
- REST (Representational State Transfer):一种架构风格,而不是一个协议,它使用 HTTP 方法(GET, POST, PUT, DELETE)来操作资源,数据格式通常轻量(如 JSON),REST API 是目前 Web 开发的主流。
- WSDL (Web Services Description Language):一个 XML 文件,用于描述 SOAP 服务的接口,包括可用的方法、参数和返回类型,客户端可以通过 WSDL 文件自动生成调用代码。
- SOAP WebService = 使用 SOAP 协议的 WebService。
- RESTful API = 一种遵循 REST 架构风格的 WebService。
实现 SOAP WebService
Python 中实现 SOAP 服务最常用的库是 spyne,它功能强大,支持将 Python 类自动映射为 SOAP 服务。
安装 spyne 和依赖
pip install spyne pip install django # 或者 flask, tornado, soapfish 等作为 WSGI 服务器 # 这里我们使用内置的 WSGI 服务器,所以不需要额外安装
实现一个简单的 SOAP 服务
我们将创建一个服务,它提供一个 say_hello 方法,接收一个 name 字符串,并返回 "Hello, [name]!"。
soap_server.py
from spyne import Application, rpc, ServiceBase, Unicode
from spyne.protocol.soap import Soap11
from spyne.server.wsgi import WsgiApplication
# 1. 定义服务类
class HelloWorldService(ServiceBase):
"""
这是一个 Spyne 服务类,它将暴露 RPC 方法。
"""
@rpc(Unicode, _returns=Unicode)
def say_hello(ctx, name):
"""
say_hello 方法。
:param ctx: 上下文对象,包含请求信息等
:param name: 一个 Unicode 字符串类型的参数
:return: 一个 Unicode 字符串类型的返回值
"""
print(f"[Server] Received request for say_hello with name: {name}")
return f"Hello, {name}!"
# 2. 创建 Spyne 应用
# tns: target namespace (目标命名空间),类似于 Java 包名
# in_protocol: 输入协议
# out_protocol: 输出协议
application = Application(
[HelloWorldService],
tns='spyne.examples.hello',
in_protocol=Soap11(validator='lxml'),
out_protocol=Soap11()
)
# 3. 将 Spyne 应用包装成 WSGI 应用
wsgi_application = WsgiApplication(application)
if __name__ == '__main__':
from wsgiref.simple_server import make_server
# 4. 启动 WSGI 服务器
host = '0.0.0.0'
port = 8000
print(f"Starting SOAP server on http://{host}:{port}")
server = make_server(host, port, wsgi_application)
server.serve_forever()
运行服务
python soap_server.py
服务将在 http://0.0.0.0:8000 启动,你可以通过浏览器访问 http://localhost:8000/?wsdl 来查看服务的 WSDL 描述文件,这个文件定义了服务的接口,是客户端调用的“说明书”。

创建 SOAP 客户端
为了测试我们的服务,我们可以用 Python 写一个客户端。
soap_client.py
from spyne import Application, rpc, ServiceBase, Unicode
from spyne.protocol.soap import Soap11
from spyne.client.wsgi import HttpClient
# 服务地址和 WSDL 地址
url = 'http://localhost:8000/?wsdl'
# 1. 创建客户端应用
# 注意:这里的 ServiceBase 可以是空的,因为我们只需要协议和地址信息
client = HttpClient(
url,
tns='spyne.examples.hello',
protocol=Soap11(),
app=Application([ServiceBase], 'spyne.examples.hello', in_protocol=Soap11(), out_protocol=Soap11())
)
# 2. 调用远程方法
try:
# 调用 say_hello 方法,传入 'Alice'
response = client.service.say_hello('Alice')
print(f"[Client] Received response: {response}")
except Exception as e:
print(f"[Client] An error occurred: {e}")
运行客户端
在另一个终端运行客户端:
python soap_client.py
预期输出:

- 服务端终端:
[Server] Received request for say_hello with name: Alice - 客户端终端:
[Client] Received response: Hello, Alice!
实现 RESTful API (更常用)
实现 RESTful API 的 Python 框架非常多,Flask, Django REST framework, FastAPI 等,这里我们选择最轻量级的 Flask 来演示。
安装 Flask
pip install Flask
实现一个简单的 RESTful API
我们将创建一个简单的用户管理 API,包含 GET /users/<user_id> 和 POST /users 两个接口。
rest_server.py
from flask import Flask, request, jsonify
# 1. 创建 Flask 应用实例
app = Flask(__name__)
# 模拟一个数据库
users = {
1: {"name": "Alice", "email": "alice@example.com"},
2: {"name": "Bob", "email": "bob@example.com"}
}
next_user_id = 3
# 2. 定义路由和处理函数
# 获取单个用户信息 (GET)
@app.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
"""
根据 user_id 获取用户信息。
:param user_id: 用户ID,从 URL 路径获取
"""
user = users.get(user_id)
if user:
return jsonify(user), 200 # 返回 JSON 数据和 HTTP 200 状态码
else:
return jsonify({"error": "User not found"}), 404 # 返回错误和 404 状态码
# 创建新用户 (POST)
@app.route('/users', methods=['POST'])
def create_user():
"""
创建一个新用户。
请求体应为 JSON 格式,包含 'name' 和 'email'。
"""
if not request.json or 'name' not in request.json or 'email' not in request.json:
return jsonify({"error": "Missing data in request"}), 400 # Bad Request
global next_user_id
new_user = {
"id": next_user_id,
"name": request.json['name'],
"email": request.json['email']
}
users[next_user_id] = new_user
next_user_id += 1
# 返回新创建的用户信息和 HTTP 201 状态码
return jsonify(new_user), 201
# 3. 运行应用
if __name__ == '__main__':
# debug=True 可以在代码修改后自动重启服务器
app.run(host='0.0.0.0', port=5000, debug=True)
运行服务
python rest_server.py
服务将在 http://0.0.0.0:5000 启动。
测试 RESTful API
你可以使用 curl 命令或 Postman 等工具来测试 API。
测试 GET /users/1
curl http://localhost:5000/users/1
预期输出:
{
"email": "alice@example.com",
"name": "Alice"
}
测试 POST /users
curl -X POST -H "Content-Type: application/json" \
-d '{"name": "Charlie", "email": "charlie@example.com"}' \
http://localhost:5000/users
预期输出:
{
"email": "charlie@example.com",
"id": 3,
"name": "Charlie"
}
总结与对比
| 特性 | SOAP WebService | RESTful API |
|---|---|---|
| 本质 | 一个协议 | 一种架构风格 |
| 数据格式 | 严格使用 XML | 常用 JSON,也支持 XML、HTML 等 |
| 标准 | 有严格的规范(WSDL, WS-*) | 无统一标准,依赖 HTTP 标准 |
| 接口发现 | 通过 WSDL 文件 | 通常通过 Swagger/OpenAPI 文档或手动阅读文档 |
| 性能 | XML 解析开销大,性能相对较低 | JSON 轻量级,性能高 |
| 安全性 | 内置安全标准和事务处理 | 依赖 HTTPS 和应用层安全 |
| 适用场景 | 企业级应用、金融、电信等对事务和安全要求高的场景 | 移动应用、Web 前后端分离、微服务、公开 API |
| Python 实现 | spyne, zeep (客户端) |
Flask, Django, FastAPI, Falcon |
如何选择?
- 如果你的项目需要遵循严格的行业标准,与老式企业系统集成,或者需要强大的事务支持,SOAP 是一个不错的选择。
- 对于绝大多数现代 Web 应用,特别是需要构建面向公众的 API 或进行前后端分离开发时,RESTful API 是事实上的标准,因为它更简单、更灵活、性能也更好。FastAPI 是目前非常推荐的新一代 Python Web 框架,它性能极高,并且自带 API 文档(Swagger UI)。
