最近迷上了买相机,大疆Pocket、Insta Go3、大疆Mini3、佳能50D、vivo徕卡人像大师(狗头),在买配件的时候,发现1/4螺口简直是神中之神,这个万能接口让我想到计算机设计中的接口,遂有此篇——
接口的代码格式因编程语言而异,下面提供两个经典接口的示例,分别是 REST API 和 gRPC,并对比它们的区别。
- REST API 示例(Python Flask)
REST API 使用 HTTP 协议,通过不同的 HTTP 方法(GET、POST、PUT、DELETE)操作资源,返回 JSON 或 XML 格式的数据。
from flask import Flask, jsonify, request
app = Flask(__name__)
# 模拟数据
books = [
{"id": 1, "title": "Python Crash Course", "author": "Eric Matthes"},
{"id": 2, "title": "Clean Code", "author": "Robert C. Martin"}
]
# 获取所有书籍
@app.route('/api/books', methods=['GET'])
def get_books():
return jsonify(books)
# 获取单个书籍
@app.route('/api/books/<int:book_id>', methods=['GET'])
def get_book(book_id):
book = next((b for b in books if b['id'] == book_id), None)
if book is None:
return jsonify({"error": "Book not found"}), 404
return jsonify(book)
# 添加书籍
@app.route('/api/books', methods=['POST'])
def add_book():
data = request.get_json()
new_book = {
"id": len(books) + 1,
"title": data.get('title'),
"author": data.get('author')
}
books.append(new_book)
return jsonify(new_book), 201
if __name__ == '__main__':
app.run(debug=True)
- gRPC 示例(Python + Protocol Buffers)
gRPC 使用 Protocol Buffers 定义服务和消息格式,通过 HTTP/2 进行通信,提供强类型接口和高性能。
首先定义 .proto 文件(book.proto):
syntax = "proto3";
package book;
// 定义消息格式
message Book {
int32 id = 1;
string title = 2;
string author = 3;
}
message BookRequest {
int32 id = 1;
}
message BookList {
repeated Book books = 1;
}
// 定义服务接口
service BookService {
// 获取所有书籍
rpc GetBooks(google.protobuf.Empty) returns (BookList);
// 获取单个书籍
rpc GetBook(BookRequest) returns (Book);
// 添加书籍
rpc AddBook(Book) returns (Book);
}
然后实现服务端(server.py):
import grpc
from concurrent import futures
import book_pb2
import book_pb2_grpc
class BookService(book_pb2_grpc.BookServiceServicer):
def __init__(self):
self.books = [
book_pb2.Book(id=1, title="Python Crash Course", author="Eric Matthes"),
book_pb2.Book(id=2, title="Clean Code", author="Robert C. Martin")
]
def GetBooks(self, request, context):
return book_pb2.BookList(books=self.books)
def GetBook(self, request, context):
for book in self.books:
if book.id == request.id:
return book
context.set_code(grpc.StatusCode.NOT_FOUND)
return book_pb2.Book()
def AddBook(self, request, context):
new_book = book_pb2.Book(
id=len(self.books) + 1,
title=request.title,
author=request.author
)
self.books.append(new_book)
return new_book
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
book_pb2_grpc.add_BookServiceServicer_to_server(BookService(), server)
server.add_insecure_port('[::]:50051')
server.start()
print("Server started, listening on port 50051")
server.wait_for_termination()
if __name__ == '__main__':
serve()
幼儿园版