API Reference
Module
gRPCServer — Module
gRPCServerA native Julia implementation of a gRPC server library.
gRPCServer enables Julia developers to expose services over the gRPC protocol with support for all four RPC patterns (unary, server streaming, client streaming, bidirectional), interceptors, health checking, reflection, TLS/mTLS, and compression.
Quick Start
using gRPCServer
# Create server
server = GRPCServer("127.0.0.1", 50051)
# Register your service
register!(server, MyService())
# Start server
run(server)See the documentation for more examples and API reference.
Server Types
gRPCServer.GRPCServer — Type
GRPCServerThe main gRPC server managing connections, services, and lifecycle.
Fields
host::String: Server bind addressport::Int: Server portconfig::ServerConfig: Server configurationstatus::ServerStatus.T: Current lifecycle statedispatcher::RequestDispatcher: Request dispatcherhealth_status::Dict{String, HealthStatus.T}: Per-service health status
Example
server = GRPCServer("0.0.0.0", 50051)
register!(server, GreeterService())
run(server)gRPCServer.ServerConfig — Type
ServerConfigConfiguration container for gRPC server options.
Fields
Connection Limits
max_connections::Union{Int, Nothing}: Maximum concurrent connections (nothing = unlimited)max_concurrent_streams::Int: Maximum streams per connection (default: 100)max_concurrent_requests::Union{Int, Nothing}: Maximum concurrent requests (nothing = unlimited)max_queued_requests::Int: Maximum queued requests when at capacity (default: 1000)
Message Limits
max_message_size::Int: Maximum message size in bytes (default: 4MB)
Timeouts (in seconds)
keepalive_interval::Union{Float64, Nothing}: Interval for keepalive pings (nothing = disabled)keepalive_timeout::Float64: Timeout for keepalive response (default: 20.0)idle_timeout::Union{Float64, Nothing}: Close idle connections after this time (nothing = never)drain_timeout::Float64: Maximum time to wait for graceful shutdown (default: 30.0)
TLS
tls::Union{TLSConfig, Nothing}: TLS configuration (nothing = insecure)
Feature Toggles
enable_health_check::Bool: Enable built-in health checking service (default: false)enable_reflection::Bool: Enable gRPC reflection service (default: false)debug_mode::Bool: Include exception details in error responses (default: false)log_requests::Bool: Log all incoming requests (default: false)
Compression
compression_enabled::Bool: Enable message compression (default: true)compression_threshold::Int: Minimum bytes before compression (default: 1024)supported_codecs::Vector{CompressionCodec.T}: Supported compression codecs
Example
config = ServerConfig(
max_message_size = 8 * 1024 * 1024, # 8MB
enable_health_check = true,
enable_reflection = true,
debug_mode = false
)gRPCServer.TLSConfig — Type
TLSConfigTLS/mTLS configuration for secure connections.
Fields
cert_chain::String: Path to server certificate chain (PEM)private_key::String: Path to server private key (PEM)client_ca::Union{String, Nothing}: Path to client CA certificate for mTLSrequire_client_cert::Bool: Whether to require client certificatesmin_version::Symbol: Minimum TLS version (:TLSv1_2or:TLSv1_3)alpn_protocols::Vector{String}: Ordered ALPN protocol preference list (default["h2"])handshake_timeout_ns::Int64: Optional per-handshake timeout in nanoseconds;0leaves it unset
Example
tls = TLSConfig(
cert_chain = "/path/to/server.crt",
private_key = "/path/to/server.key",
client_ca = "/path/to/ca.crt", # For mTLS
require_client_cert = true,
min_version = :TLSv1_2,
alpn_protocols = ["h2"],
)gRPCServer.ServerStatus — Module
ServerStatusRepresents the lifecycle state of a gRPC server.
States
STOPPED: Server is not runningSTARTING: Server is binding to addressRUNNING: Server is accepting connectionsDRAINING: Server is completing in-flight requestsSTOPPING: Server is releasing resources
Context Types
gRPCServer.ServerContext — Type
ServerContextRequest-scoped context provided to handler functions.
Fields
request_id::UUID: Unique identifier for this requestmethod::String: Full method path (e.g., "/helloworld.Greeter/SayHello")authority::String: Authority from :authority pseudo-headermetadata::Dict{String, Union{String, Vector{UInt8}}}: Request metadataresponse_headers::Dict{String, Union{String, Vector{UInt8}}}: Response headers to sendtrailers::Dict{String, Union{String, Vector{UInt8}}}: Trailing metadata to senddeadline::Union{DateTime, Nothing}: Request deadline (nothing = no deadline)cancelled::Bool: Whether the request has been cancelledpeer::PeerInfo: Client connection informationtrace_context::Union{Vector{UInt8}, Nothing}: Distributed tracing context
Example
function say_hello(ctx::ServerContext, request::HelloRequest)::HelloReply
@info "Request" id=ctx.request_id method=ctx.method
# Check cancellation
if is_cancelled(ctx)
throw(GRPCError(StatusCode.CANCELLED, "Request cancelled"))
end
# Set response header
set_header!(ctx, "x-request-id", string(ctx.request_id))
# Check deadline
remaining = remaining_time(ctx)
if remaining !== nothing && remaining < 0
throw(GRPCError(StatusCode.DEADLINE_EXCEEDED, "Deadline exceeded"))
end
HelloReply(message = "Hello, $(request.name)!")
endgRPCServer.PeerInfo — Type
PeerInfoClient connection information.
Fields
address::Union{IPv4, IPv6}: Client IP addressport::Int: Client portcertificate::Union{Vector{UInt8}, Nothing}: Client certificate for mTLS (DER-encoded)
Example
peer = ctx.peer
@info "Client connected from $(peer.address):$(peer.port)"Service Registration
gRPCServer.ServiceDescriptor — Type
ServiceDescriptorDescribes a gRPC service and its methods.
Fields
name::String: Fully-qualified service name (e.g., "helloworld.Greeter")methods::Dict{String, MethodDescriptor}: Methods keyed by namefile_descriptor::Union{Vector{UInt8}, Nothing}: File descriptor for reflection (optional)
Example
service = ServiceDescriptor(
"helloworld.Greeter",
Dict(
"SayHello" => MethodDescriptor(
"SayHello",
MethodType.UNARY,
"helloworld.HelloRequest",
"helloworld.HelloReply",
say_hello
)
),
nothing
)gRPCServer.MethodDescriptor — Type
MethodDescriptorDescribes a single RPC method.
Fields
name::String: Method name (e.g., "SayHello")method_type::MethodType.T: RPC pattern typeinput_type::String: Fully-qualified request message type nameoutput_type::String: Fully-qualified response message type namehandler::Function: Handler function reference
Handler Signatures by MethodType
UNARY:(ctx::ServerContext, request::T) -> RSERVER_STREAMING:(ctx::ServerContext, request::T, stream::ServerStream{R}) -> NothingCLIENT_STREAMING:(ctx::ServerContext, stream::ClientStream{T}) -> RBIDI_STREAMING:(ctx::ServerContext, stream::BidiStream{T,R}) -> Nothing
Example
method = MethodDescriptor(
"SayHello",
MethodType.UNARY,
"helloworld.HelloRequest",
"helloworld.HelloReply",
say_hello
)gRPCServer.MethodType — Module
MethodTypeClassifies RPC method patterns.
Values
UNARY: Single request, single responseSERVER_STREAMING: Single request, multiple responsesCLIENT_STREAMING: Multiple requests, single responseBIDI_STREAMING: Multiple requests, multiple responses
gRPCServer.register! — Function
register!(registry::ServiceRegistry, descriptor::ServiceDescriptor)Register a service in the registry. Also auto-registers protobuf types if Julia types were provided in MethodDescriptor.
register!(server::GRPCServer, service)Register a service with the server.
The service must implement service_descriptor(service) to provide its ServiceDescriptor.
Arguments
server::GRPCServer: The server to register withservice: A service implementation
Throws
InvalidServerStateError: If server is not in STOPPED stateServiceAlreadyRegisteredError: If service is already registered
Example
server = GRPCServer("0.0.0.0", 50051)
register!(server, GreeterService())gRPCServer.services — Function
services(server::GRPCServer) -> Vector{String}Get a list of registered service names.
Example
for service_name in services(server)
println(service_name)
endgRPCServer.service_descriptor — Function
service_descriptor(service) -> ServiceDescriptorGet the service descriptor for a service implementation.
This function should be overloaded for custom service types.
Example
struct GreeterService end
function gRPCServer.service_descriptor(::GreeterService)
ServiceDescriptor(
"helloworld.Greeter",
Dict(
"SayHello" => MethodDescriptor(
"SayHello", MethodType.UNARY,
"helloworld.HelloRequest", "helloworld.HelloReply",
say_hello
)
),
nothing
)
endStream Types
gRPCServer.ServerStream — Type
ServerStream{T}Outgoing stream for server streaming and bidirectional RPCs.
Type parameter T is the response message type.
Methods
send!(stream, message): Send a messageclose!(stream): End the stream
Example
function list_features(ctx::ServerContext, request::Rectangle, stream::ServerStream{Feature})
for feature in find_features(request)
send!(stream, feature)
end
endgRPCServer.ClientStream — Type
ClientStream{T}Incoming stream for client streaming and bidirectional RPCs.
Type parameter T is the request message type.
Implements the Julia iterator interface for use in for loops.
Example
function record_route(ctx::ServerContext, stream::ClientStream{Point})::RouteSummary
point_count = 0
for point in stream
point_count += 1
# Process each point
end
return RouteSummary(point_count=point_count)
endgRPCServer.BidiStream — Type
BidiStream{T, R}Bidirectional stream combining input (T) and output (R) streams.
Type parameters:
T: Request message type (incoming)R: Response message type (outgoing)
Implements the iterator interface for incoming messages and provides send! for outgoing messages.
Example
function route_chat(ctx::ServerContext, stream::BidiStream{RouteNote, RouteNote})
for note in stream # Iterate incoming messages
# Echo back each note
send!(stream, note)
end
endgRPCServer.send! — Function
send!(stream::ServerStream{T}, message::T) where T
send!(stream::ServerStream{T}, message::T; compress::Bool=true) where TSend a message on the server stream.
Arguments
stream::ServerStream{T}: The stream to send onmessage::T: The message to sendcompress::Bool=true: Whether to compress the message (if compression is negotiated)
Throws
StreamCancelledError: If the stream has been cancelledArgumentError: If the stream is closed
Example
send!(stream, Feature(name="Feature 1", location=Point(latitude=1, longitude=2)))send!(stream::BidiStream{T, R}, message::R) where {T, R}
send!(stream::BidiStream{T, R}, message::R; compress::Bool=true) where {T, R}Send a message on the bidirectional stream.
Example
send!(stream, RouteNote(message="Hello", location=point))gRPCServer.close! — Function
close!(stream::BidiStream)Close the output side of the bidirectional stream.
Error Handling
gRPCServer.StatusCode — Module
StatusCodeStandard gRPC status codes per specification.
Status Codes
OK(0): Not an error; returned on successCANCELLED(1): Operation was cancelledUNKNOWN(2): Unknown errorINVALID_ARGUMENT(3): Invalid argument providedDEADLINE_EXCEEDED(4): Deadline expired before completionNOT_FOUND(5): Requested entity not foundALREADY_EXISTS(6): Entity already existsPERMISSION_DENIED(7): Permission deniedRESOURCE_EXHAUSTED(8): Resource exhaustedFAILED_PRECONDITION(9): Precondition check failedABORTED(10): Operation abortedOUT_OF_RANGE(11): Value out of rangeUNIMPLEMENTED(12): Operation not implementedINTERNAL(13): Internal errorUNAVAILABLE(14): Service unavailableDATA_LOSS(15): Data loss or corruptionUNAUTHENTICATED(16): Request not authenticated
gRPCServer.GRPCError — Type
GRPCError <: ExceptionException type for gRPC errors with status code, message, and optional details.
Fields
code::StatusCode.T: The gRPC status codemessage::String: Human-readable error messagedetails::Vector{Any}: Additional error details (rich error model)
Example
throw(GRPCError(StatusCode.NOT_FOUND, "User not found", []))
throw(GRPCError(StatusCode.INVALID_ARGUMENT, "Name cannot be empty"))gRPCServer.BindError — Type
BindError <: ExceptionException thrown when the server fails to bind to the configured address.
Fields
message::String: Description of the bind failurecause::Union{Exception, Nothing}: Underlying exception if available
gRPCServer.ServiceAlreadyRegisteredError — Type
ServiceAlreadyRegisteredError <: ExceptionException thrown when attempting to register a service with a name that already exists.
Fields
service_name::String: The duplicate service name
gRPCServer.InvalidServerStateError — Type
InvalidServerStateError <: ExceptionException thrown when an operation is attempted in an invalid server state.
Fields
expected::ServerStatus.T: The expected server stateactual::ServerStatus.T: The actual server state
gRPCServer.MethodSignatureError — Type
MethodSignatureError <: ExceptionException thrown when a handler method has an invalid signature.
Fields
method_name::String: The method with invalid signatureexpected::String: Description of expected signatureactual::String: Description of actual signature
gRPCServer.StreamCancelledError — Type
StreamCancelledError <: ExceptionException thrown when a stream operation is attempted on a cancelled stream.
Fields
reason::String: The reason for cancellation
gRPCServer.status_code_to_http — Function
status_code_to_http(code::StatusCode.T) -> IntMap a gRPC status code to the appropriate HTTP status code.
gRPCServer.exception_to_status_code — Function
exception_to_status_code(e::Exception) -> StatusCode.TMap a Julia exception to a gRPC status code.
gRPCServer.http2_to_grpc_status — Function
http2_to_grpc_status(http2_error_code::UInt32) -> StatusCode.TMap an HTTP/2 error code to a gRPC status code.
This mapping is per the gRPC HTTP/2 protocol specification: https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md
HTTP/2 Error Code Mappings
- NOERROR (0x0) → INTERNAL (unexpected for RSTSTREAM)
- PROTOCOL_ERROR (0x1) → INTERNAL
- INTERNAL_ERROR (0x2) → INTERNAL
- FLOWCONTROLERROR (0x3) → INTERNAL
- SETTINGS_TIMEOUT (0x4) → INTERNAL
- STREAM_CLOSED (0x5) → INTERNAL
- FRAMESIZEERROR (0x6) → INTERNAL
- REFUSED_STREAM (0x7) → UNAVAILABLE
- CANCEL (0x8) → CANCELLED
- COMPRESSION_ERROR (0x9) → INTERNAL
- CONNECT_ERROR (0xa) → INTERNAL
- ENHANCEYOURCALM (0xb) → RESOURCE_EXHAUSTED
- INADEQUATESECURITY (0xc) → PERMISSIONDENIED
- HTTP11_REQUIRED (0xd) → INTERNAL
Example
grpc_status = http2_to_grpc_status(0x08) # CANCEL → CANCELLEDhttp2_to_grpc_status(http2_error_code::Integer) -> StatusCode.TConvenience method accepting any integer type.
Interceptors
gRPCServer.Interceptor — Type
InterceptorAbstract type for gRPC interceptors.
Interceptors are callables that wrap handler execution, allowing for cross-cutting concerns like logging, authentication, metrics, and error handling.
Required Interface
Subtypes must be callable with signature:
(interceptor)(ctx::ServerContext, request_or_stream, info::MethodInfo, next::Function) -> responseArguments
ctx::ServerContext: Request contextrequest_or_stream: Request message (unary/server streaming) or stream (client/bidi streaming)info::MethodInfo: Method informationnext::Function: Next handler in the chain (call to continue processing)
Example
struct AuthInterceptor <: Interceptor
required_scope::String
end
function (i::AuthInterceptor)(ctx, request, info, next)
token = get_metadata_string(ctx, "authorization")
if token === nothing
throw(GRPCError(StatusCode.UNAUTHENTICATED, "Missing authorization"))
end
# Validate token and check scope
if !validate_token(token, i.required_scope)
throw(GRPCError(StatusCode.PERMISSION_DENIED, "Insufficient scope"))
end
return next(ctx, request)
endgRPCServer.MethodInfo — Type
MethodInfoInformation about the method being called, provided to interceptors.
Fields
service_name::String: Fully-qualified service name (e.g., "helloworld.Greeter")method_name::String: Method name (e.g., "SayHello")method_type::MethodType.T: RPC pattern type
Example
struct LoggingInterceptor <: Interceptor end
function (::LoggingInterceptor)(ctx, request, info::MethodInfo, next)
@info "Calling" service=info.service_name method=info.method_name
return next(ctx, request)
endgRPCServer.LoggingInterceptor — Type
LoggingInterceptor <: InterceptorBuilt-in interceptor that logs request/response information.
Fields
log_requests::Bool: Log incoming requests (default: true)log_responses::Bool: Log responses (default: true)log_errors::Bool: Log errors (default: true)
Example
add_interceptor!(server, LoggingInterceptor())gRPCServer.MetricsInterceptor — Type
MetricsInterceptor <: InterceptorBuilt-in interceptor that collects request metrics.
Fields
on_request::Function: Called with (method, request_size) on each requeston_response::Function: Called with (method, status, durationms, responsesize) on each response
Example
metrics = MetricsInterceptor(
on_request = (method, size) -> increment_counter("grpc_requests", method),
on_response = (method, status, ms, size) -> record_histogram("grpc_duration", ms, method, status)
)
add_interceptor!(server, metrics)gRPCServer.TimeoutInterceptor — Type
TimeoutInterceptor <: InterceptorBuilt-in interceptor that enforces request deadlines.
Fields
default_timeout_ms::Union{Int, Nothing}: Default timeout in milliseconds if none specified
Example
add_interceptor!(server, TimeoutInterceptor(default_timeout_ms=30000)) # 30 second defaultgRPCServer.RecoveryInterceptor — Type
RecoveryInterceptor <: InterceptorBuilt-in interceptor that catches panics and converts them to gRPC errors.
Fields
include_stack_trace::Bool: Include stack trace in error message (debug mode only)
Example
add_interceptor!(server, RecoveryInterceptor(include_stack_trace=true))gRPCServer.add_interceptor! — Function
add_interceptor!(dispatcher::RequestDispatcher, interceptor::Interceptor)Add a global interceptor.
add_interceptor!(dispatcher::RequestDispatcher, service_name::String, interceptor::Interceptor)Add a service-specific interceptor.
add_interceptor!(server::GRPCServer, interceptor::Interceptor)Add a global interceptor that applies to all services.
Example
add_interceptor!(server, LoggingInterceptor())
add_interceptor!(server, MetricsInterceptor())add_interceptor!(server::GRPCServer, service_name::String, interceptor::Interceptor)Add an interceptor for a specific service.
Example
add_interceptor!(server, "helloworld.Greeter", AuthInterceptor())Health Checking
gRPCServer.HealthStatus — Module
HealthStatusService health state for the health checking service.
Values
UNKNOWN: Health status is unknownSERVING: Service is healthy and accepting requestsNOT_SERVING: Service is not healthySERVICE_UNKNOWN: Service is not registered
gRPCServer.set_health! — Function
set_health!(server::GRPCServer, status::HealthStatus.T)Set the health status for the overall server.
Example
set_health!(server, HealthStatus.NOT_SERVING) # Server entering maintenanceset_health!(server::GRPCServer, service_name::String, status::HealthStatus.T)Set the health status for a specific service.
Example
set_health!(server, "helloworld.Greeter", HealthStatus.NOT_SERVING)gRPCServer.get_health — Function
get_health(server::GRPCServer, service_name::String="") -> HealthStatus.TGet the health status for a service (or overall server if empty string).
Reflection Support
gRPCServer.HEALTH_DESCRIPTOR — Constant
HEALTH_DESCRIPTOR::Vector{Vector{UInt8}}Extracted FileDescriptorProto messages for the gRPC Health service (grpc.health.v1). Each element is a serialized FileDescriptorProto that can be returned by the reflection service.
Generated from: specs/001-grpc-server/contracts/health.proto
gRPCServer.REFLECTION_DESCRIPTOR — Constant
REFLECTION_DESCRIPTOR::Vector{Vector{UInt8}}Extracted FileDescriptorProto messages for the gRPC Server Reflection service (grpc.reflection.v1alpha). Each element is a serialized FileDescriptorProto that can be returned by the reflection service.
Generated from: specs/001-grpc-server/contracts/reflection.proto
gRPCServer.has_health_descriptor — Function
has_health_descriptor() -> BoolCheck if the Health service descriptor is available.
gRPCServer.has_reflection_descriptor — Function
has_reflection_descriptor() -> BoolCheck if the Reflection service descriptor is available.
Server Lifecycle
gRPCServer.start! — Function
start!(server::GRPCServer)Start the server and begin accepting connections.
This is a non-blocking call. Use run(server) for blocking operation.
Throws
InvalidServerStateError: If server is not in STOPPED stateBindError: If the server cannot bind to the address
Example
start!(server)
# Server is now running in backgroundgRPCServer.stop! — Function
stop!(server::GRPCServer; force::Bool=false, timeout::Float64=0.0)Stop the server.
Arguments
server::GRPCServer: The server to stopforce::Bool=false: If true, immediately close all connectionstimeout::Float64=0.0: Override drain timeout (0 = use config)
Throws
InvalidServerStateError: If server is not running
Example
stop!(server) # Graceful shutdown
stop!(server; force=true) # Immediate shutdownTLS
gRPCServer.reload_tls! — Function
reload_tls!(server::GRPCServer)Reload TLS certificates from disk.
This allows certificate rotation without server restart.
Throws
InvalidServerStateError: If server is not runningArgumentError: If TLS is not configured
Example
reload_tls!(server) # Reload certificatesContext Operations
PureHTTP2.set_header! — Function
set_header!(ctx::ServerContext, key::String, value::String)
set_header!(ctx::ServerContext, key::String, value::Vector{UInt8})Set a response header to be sent before the response body.
Headers must be set before the first response message is sent. Binary headers should have a "-bin" suffix in the key name.
Example
set_header!(ctx, "x-custom-header", "custom-value")
set_header!(ctx, "x-binary-data-bin", UInt8[0x01, 0x02, 0x03])gRPCServer.set_trailer! — Function
set_trailer!(ctx::ServerContext, key::String, value::String)
set_trailer!(ctx::ServerContext, key::String, value::Vector{UInt8})Set trailing metadata to be sent after the response body.
Trailers are sent at the end of the response stream and can be used to communicate status information determined during processing.
Example
set_trailer!(ctx, "x-processing-time", "150ms")PureHTTP2.get_metadata — Function
get_metadata(ctx::ServerContext, key::String) -> Union{String, Vector{UInt8}, Nothing}Get request metadata by key (case-insensitive).
Example
auth = get_metadata(ctx, "authorization")
if auth === nothing
throw(GRPCError(StatusCode.UNAUTHENTICATED, "Missing authorization"))
endgRPCServer.get_metadata_string — Function
get_metadata_string(ctx::ServerContext, key::String) -> Union{String, Nothing}Get request metadata as a string (returns nothing for binary metadata).
gRPCServer.get_metadata_binary — Function
get_metadata_binary(ctx::ServerContext, key::String) -> Union{Vector{UInt8}, Nothing}Get request metadata as binary (converts strings to bytes if needed).
gRPCServer.remaining_time — Function
remaining_time(ctx::ServerContext) -> Union{Float64, Nothing}Get the remaining time until the deadline in seconds.
Returns nothing if no deadline is set. Returns negative value if deadline has passed.
Example
remaining = remaining_time(ctx)
if remaining !== nothing && remaining < 0
throw(GRPCError(StatusCode.DEADLINE_EXCEEDED, "Deadline exceeded"))
endgRPCServer.is_cancelled — Function
is_cancelled(ctx::ServerContext) -> BoolCheck if the request has been cancelled by the client.
Example
if is_cancelled(ctx)
throw(GRPCError(StatusCode.CANCELLED, "Request cancelled by client"))
endis_cancelled(stream::ClientStream) -> BoolCheck if the stream has been cancelled.
is_cancelled(stream::BidiStream) -> BoolCheck if the stream has been cancelled.
Compression
gRPCServer.CompressionCodec — Module
CompressionCodecSupported compression algorithms for gRPC messages.
Values
IDENTITY: No compressionGZIP: Gzip compressionDEFLATE: Deflate compression
gRPCServer.compress — Function
compress(data::Vector{UInt8}, codec::CompressionCodec.T) -> Vector{UInt8}Compress data using the specified codec.
gRPCServer.decompress — Function
decompress(data::Vector{UInt8}, codec::CompressionCodec.T) -> Vector{UInt8}Decompress data using the specified codec.
gRPCServer.codec_name — Function
codec_name(codec::CompressionCodec.T) -> StringGet the gRPC encoding name for a compression codec.
gRPCServer.parse_codec — Function
parse_codec(name::AbstractString) -> Union{CompressionCodec.T, Nothing}Parse a gRPC encoding name to a compression codec. Returns nothing if the encoding is not supported.
gRPCServer.negotiate_compression — Function
negotiate_compression(
client_encodings::Vector{CompressionCodec.T},
server_codecs::Vector{CompressionCodec.T}
) -> CompressionCodec.TNegotiate compression codec between client and server. Returns the first codec supported by both, preferring client order. Falls back to IDENTITY if no common codec.
HTTP/2 Backend Abstraction
gRPCServer.jl supports pluggable HTTP/2 backends via an abstract type and a connection-factory method. See HTTP/2 Backends for the full guide.
gRPCServer.AbstractHTTP2Backend — Type
AbstractHTTP2BackendAbstract type representing an HTTP/2 backend for gRPCServer.jl.
Any HTTP/2 backend must subtype AbstractHTTP2Backend and implement create_connection to return an HTTP/2 connection object.
The connection object returned by create_connection must be compatible with PureHTTP2.jl's HTTP2Connection interface, supporting:
- Connection lifecycle:
process_preface,process_frame,is_open - Stream management:
get_stream,remove_stream,can_send_on_stream - Sending:
send_headers,send_data,send_trailers,send_rst_stream,send_goaway - Frame I/O:
Frame,encode_frame,decode_frame_header
See the HTTP/2 Backends documentation page for details on implementing a custom backend.
gRPCServer.PureHTTP2Backend — Type
PureHTTP2Backend <: AbstractHTTP2BackendDefault HTTP/2 backend using PureHTTP2.jl.
This backend delegates all HTTP/2 operations to the PureHTTP2 package, which provides a pure-Julia implementation of the HTTP/2 protocol (RFC 7540) including HPACK header compression (RFC 7541), stream management, and flow control.
gRPCServer.create_connection — Function
create_connection(backend::AbstractHTTP2Backend)Create a new HTTP/2 connection using the specified backend.
Returns an HTTP/2 connection object that will be used to manage a single client connection. The returned object must support the full HTTP/2 connection interface (see AbstractHTTP2Backend for requirements).
Examples
backend = PureHTTP2Backend()
conn = create_connection(backend) # Returns a PureHTTP2.HTTP2ConnectiongRPCServer.HTTPjlBackend — Type
HTTPjlBackend <: AbstractHTTP2BackendHTTP/2 backend backed by HTTP.jl (>= 2.0.0).
HTTP.jl owns the TCP listener and the TLS/ALPN handshake; this backend delegates the HTTP/2 protocol (frames, HPACK, flow control, trailers) to HTTP.jl and adapts each HTTP.Stream to the AbstractGRPCStream contract.
Constructing an HTTPjlBackend validates that the loaded HTTP.jl can serve HTTP/2 and raises a clear error otherwise.
Known limitations (current HTTP.jl)
- No configurable max-concurrent-streams limit (HTTP.jl advertises none).
- No live TLS certificate reload (
reload_tls!); HTTP.jl owns the TLS context.
Select PureHTTP2Backend() if you need either capability.
gRPCServer.Nghttp2Backend — Type
Nghttp2Backend <: AbstractHTTP2BackendHTTP/2 backend backed by the nghttp2 C library through Nghttp2Wrapper.jl.
Nghttp2Wrapper is an optional dependency. Load it before constructing the backend:
using gRPCServer, Nghttp2Wrapper
server = GRPCServer("127.0.0.1", 50051; http2_backend = Nghttp2Backend())Supported RPC types
Unary and client-streaming calls only. Nghttp2Wrapper's server handler receives a fully buffered request and returns a fully buffered response, so a handler cannot emit messages as it produces them — server-streaming and bidirectional calls are rejected at dispatch rather than silently truncated. Its ROADMAP Milestone 7 tracks the incremental handler that would lift this.
Select HTTPjlBackend for the full set.
Raised stream-handler contract (HTTP.jl backend)
The HTTP.jl backend requires a higher-level contract than the connection factory: the backend owns the serve loop and presents each gRPC call as an AbstractGRPCStream. This contract is introduced for the HTTP.jl backend; the request-path integration is in progress.
gRPCServer.AbstractGRPCStream — Type
AbstractGRPCStreamRepresents a single in-flight gRPC call (one HTTP/2 stream) as seen by the gRPC dispatch layer, independent of which HTTP/2 backend produced it.
A backend adapter presents each incoming call as an AbstractGRPCStream and implements the stream operations: grpc_path, request_metadata, read_message!, is_cancelled, send_response_headers!, send_message!, send_trailers!, and reset!.
gRPCServer.serve_grpc — Function
serve_grpc(backend::AbstractHTTP2Backend, server, on_call) -> NothingOwn the accept loop for server and invoke on_call(stream::AbstractGRPCStream) once per incoming gRPC call. Backends must validate the HTTP/2 connection preface (h2c) and/or negotiate ALPN h2 (TLS), surface each request's :path and metadata via the stream, honor graceful shutdown when the server leaves the RUNNING state, and fail fast (before accepting traffic) when the backend cannot serve gRPC HTTP/2.
This is the higher-level extension point that complements create_connection; see the HTTP/2 Backends documentation for details.
HTTP/2 Stream State
These functions are used for advanced stream state management, particularly for handling edge cases with client disconnection. They come from PureHTTP2.jl and are re-exported by gRPCServer.
can_send(stream)— check whether a stream is in a state that accepts outbound dataStreamError— exception type for HTTP/2 stream-level errors