English | 中文
When a service's protocol is http in trpc_python.yaml, the framework listens with aiohttp and serves HTTP/1.1. HTTP/2 and HTTP/3 are not supported.
The same HTTP service configuration supports two styles. Use either one, or both together. A runnable example is in examples/http:
- Generic HTTP RPC. The interface is still defined in protobuf and generated as stub code. Only the transport changes to HTTP.
- Standard HTTP. No
.protofile. Register routes with the@routedecorator and handle the HTTP request and response yourself.
TLS. To serve HTTPS, set both
tls_key(private key path) andtls_cert(certificate path) on thatservice.
The interface and registration are the same as for a unary RPC service: write a .proto, generate stub code, then call create_server(), register_*_server(), and server.serve(). The only difference is protocol: http in YAML:
server:
service:
- name: trpc.trpc_python_group.helloworld.Greeter
ip: 127.0.0.1
port: 9002
network: tcp
protocol: http
timeout: 5000The RPC method path is the HTTP URL path. For SayHello in the configuration above, the address is:
http://127.0.0.1:9002/trpc.trpc_python_group.helloworld.Greeter/SayHello
When the service is registered with fix_rpc_name=True, the service-name span in the URL path is replaced by that service's YAML name.
- GET. The query string is the request payload and is deserialized as
Form. - Other methods, such as POST. The framework reads the HTTP body. The default deserialization is
JSON. TheContent-Typerequest header selects another format:
Content-Type |
Serialization |
|---|---|
application/json |
JSON (default) |
application/protobuf, application/x-protobuf, application/pb, application/proto |
Protobuf |
application/x-www-form-urlencoded |
Form |
application/octet-stream |
Raw bytes |
- Request control headers. tRPC call-control fields travel in HTTP headers with a
trpc-prefix, includingtrpc-timeout,trpc-caller,trpc-callee,trpc-request-id, andtrpc-trans-info.Content-TypeandContent-Encodingkeep their standard HTTP names. - Response error codes. A framework error code is returned in
trpc-ret. A business error code is returned intrpc-func-ret. - Filters and fallback. Every path that
@routedoes not match falls through to the generic HTTP RPC entry.aiohttpfirst attaches the request object to the context. The server filter chain then runs as usual, and the transport skips tRPC binary-frame decompression and the default protobuf deserialization.
Standard HTTP does not need a .proto or generated stub code. Register handlers with the @route decorator.
@routerecords the route when the module is imported. Import the module that defines the routes beforecreate_server().
from aiohttp import web
from aiohttp.web_request import Request
from trpc_sdk.abc import TrpcContext
from trpc_sdk.http import get_http_response
from trpc_sdk.http import register_static
from trpc_sdk.http import route
from trpc_sdk.http import set_http_rsp_header
@route("/normal_http")
async def normal_http(ctx: TrpcContext, request: Request) -> web.Response:
return web.json_response({"data": "json"})
@route("/bind_service_name", service_name="trpc.trpc_python_group.helloworld.Normal")
async def bind_service_name(ctx: TrpcContext, request: Request) -> web.Response:
rsp = get_http_response(ctx)
rsp.headers["url_path"] = request.path
set_http_rsp_header(ctx, header={"test": "data"})
return web.json_response({"data": "json"})
register_static("/static", "/path/to/files")route(path, method="*", service_name=None):
method. The default is"*", which matches any HTTP method (GET, POST, and so on).service_name.- When it is omitted (
None), everyservicein the configuration withprotocol: httpmounts this route. - When it is set, only the
servicewhose YAMLnamematches exactly mounts it.
- When it is omitted (
The handler signature is async def handler(ctx: TrpcContext, request: Request). It receives the call context and an aiohttp Request. Two return styles are supported:
- Return a
web.StreamResponsedirectly (includingweb.Responseandweb.json_response). The framework uses that object as the HTTP response. - Return
bytesorstr. The framework writes them into the body of a response it prepared ahead of time. In this mode:get_http_response(ctx)returns that prepared response, so the handler can change its status code or headers.set_http_rsp_header(ctx, header=...)records headers. The framework merges them into the final response after the handler returns.
register_static(prefix, path_to_folder) mounts a local directory at a URL prefix.
An incoming HTTP request is matched in this order:
- An exact
@route - A directory registered with
register_static - The generic HTTP RPC fallback
Filter chain. Standard HTTP routes also enter the server filter chain. The
reqpassed tofilter.handle(ctx, req, rsp)is theaiohttpRequest, not a protobuf message.