API Reference

Module

gRPCServerModule
gRPCServer

A 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 serverserver = GRPCServer("127.0.0.1", 50051)# Register your serviceregister!(server, MyService())# Start serverrun(server)

See the documentation for more examples and API reference.

source

Server Types

gRPCServer.GRPCServerType
GRPCServer

The main gRPC server managing connections, services, and lifecycle.

Fields

  • host::String: Server bind address
  • port::Int: Server port
  • config::ServerConfig: Server configuration
  • status::ServerStatus.T: Current lifecycle state
  • dispatcher::RequestDispatcher: Request dispatcher
  • health_status::Dict{String, HealthStatus.T}: Per-service health status
  • inflight::Base.Threads.Atomic{Int}: Requests currently admitted into dispatch (load shedding)
  • shed_total::Base.Threads.Atomic{Int}: Total requests rejected at the concurrency cap
  • context::Any: Server-level payload threaded into each request's ServerContext.payload

Configuration keywords

The HTTP/2 backend is selected with http2_backend::AbstractHTTP2Backend (default HTTPjlBackend); context::Any carries a server-level payload. The remaining configuration keywords mirror the ServerConfig fields: max_message_size, max_receive_message_length, max_send_message_length, max_concurrent_streams, max_connections, max_concurrent_requests, max_queued_requests, keepalive_interval, keepalive_timeout, idle_timeout, drain_timeout, read_header_timeout, read_timeout, write_timeout, max_header_bytes, reuseaddr, backlog, tls::Union{TLSConfig, Nothing}, enable_health_check, enable_reflection, debug_mode, log_requests, compression_enabled, compression_threshold, supported_codecs, h2_initial_window_size, h2_connection_window_size.

Backends do not support every feature. Explicitly specifying a keyword the chosen backend cannot honor raises UnsupportedFeatureError at construction instead of silently ignoring it (omitted keywords never raise). Per-backend defaults and the supported keyword set are declared by backend_defaults and backend_capabilities; for convenience, see the backend-specific constructors GRPCServerHTTPJl, GRPCServerPureHTTP2, and GRPCServerNghttp2, whose docstrings list each backend's raising keywords.

Example

server = GRPCServer("0.0.0.0", 50051)register!(server, GreeterService())run(server)
source
gRPCServer.ServerConfigType
ServerConfig

Configuration 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 (default: 1024; nothing or 0 = unlimited, matching the legacy csvance semantics). The admission gate sheds a call arriving past the cap immediately with a trailers-only RESOURCE_EXHAUSTED status — no queue, no waiting (see max_queued_requests). Ships enabled because HTTP.jl allows 100 concurrent streams per connection, so with the cap unset N connections yield 100·N concurrent handler tasks; 1024 bounds that by default while staying well above typical concurrency.
  • max_queued_requests::Int: NOT IMPLEMENTED — accepted for API compatibility only. No request queue exists: a call arriving past max_concurrent_requests is shed immediately with a trailers-only RESOURCE_EXHAUSTED status (no queueing, no waiting). The value has no effect, and explicitly setting it at GRPCServer construction raises UnsupportedFeatureError (default: 1000)

Message Limits

  • max_message_size::Int: Maximum message size in bytes (default: 4MB). Seeds both the receive and send caps; override one side with max_receive_message_length / max_send_message_length (each defaults to max_message_size). The receive cap is enforced by the framing layer on incoming request messages (HTTPjl backend); the send cap is enforced when encoding response messages. The ServerConfig.max_message_size field always reports the larger of the two.

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 (default: 300; nothing = never). Aligns with the legacy serve! default. A connection that stops sending bytes — including one holding a partial request body — is closed after this window, bounding slow-body memory accrual.
  • drain_timeout::Float64: Maximum time to wait for graceful shutdown (default: 30.0)
  • read_header_timeout::Union{Float64, Nothing}: Max seconds to read request headers before the connection is closed (default: 30.0; nothing disables). Passed through to the HTTP.jl listener.
  • read_timeout::Union{Float64, Nothing}: Max seconds to read request data (nothing = disabled, the default). Enabling it defends against a peer that trickles or never finishes a request body, but it also terminates legitimately idle long-lived streaming connections, so set it only for unary or short-lived workloads — idle_timeout (on by default) already bounds stalled bodies at coarser granularity. Passed through to the HTTP.jl listener.
  • write_timeout::Union{Float64, Nothing}: Max seconds to write response data (nothing = disabled, the default). Passed through to the HTTP.jl listener.

Deadline semantics

grpc-timeout is parsed strictly into ctx.deadline (INVALID_ARGUMENT if malformed). The deadline is enforced at two points, never mid-execution: a fail-fast pre-check before the handler runs (an already-expired deadline fails with trailers-only DEADLINE_EXCEEDED and the handler is not invoked), and a post-return mapping once the handler has finished. A handler that runs past its deadline is not interrupted — it runs to completion and its result is then mapped to DEADLINE_EXCEEDED. Handlers that must bound their own runtime should check remaining_time/is_cancelled cooperatively or install TimeoutInterceptor (also pre-check-only). Watchdog-based cancellation and a server-side default deadline are future work. Unbounded handler runtime is the main amplification vector for resource exhaustion: pair cooperative deadline checks with a max_concurrent_requests cap sized to memory (see the DoS posture note below).

DoS posture

The server trusts a peer only up to the configured limits. The shipped defaults are conservative for a reason: HTTP.jl allows 100 concurrent streams per connection, so without a cap N connections imply 100·N concurrent handler tasks, and a stalled request body holds memory until the peer finishes it or the connection is reaped. The defaults bound both — max_concurrent_requests = 1024 caps concurrent handler tasks (further requests are shed with RESOURCE_EXHAUSTED), and idle_timeout = 300 closes connections that stop sending bytes. Still size max_concurrent_requests explicitly to the host's memory and the configured max_message_size in production, and treat any handler that can run for a long time as a DoS vector (see Deadline semantics and SECURITY.md).

HTTP.jl listener knobs (legacy serve! pass-throughs)

  • max_header_bytes::Int: Maximum request-header size in bytes (default: 1MiB)
  • reuseaddr::Bool: Allow reusing the address on restart (default: true)
  • backlog::Int: Connection backlog for the listener (default: 128)

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

Backend gating

ServerConfig itself is backend-agnostic and always constructible. At GRPCServer construction, however, a configuration keyword that is explicitly set but unsupported by the selected HTTP/2 backend raises UnsupportedFeatureError instead of being silently ignored (omitted keywords never raise). This applies to: max_connections, max_queued_requests, keepalive_interval, keepalive_timeout, the HTTP.jl listener timeouts and knobs, the h2-window keywords, drain_timeout (some backends), send-side compression, mTLS / TLS sub-features (on Nghttp2Backend), enable_reflection (on Nghttp2Backend), and max_concurrent_streams (on PureHTTP2Backend and Nghttp2Backend — the HTTPjlBackend supports it). See HTTP/2 Backends for the per-backend matrix.

Example

config = ServerConfig(    max_message_size = 8 * 1024 * 1024,  # 8MB    enable_health_check = true,    enable_reflection = true,    debug_mode = false)
source
gRPCServer.TLSConfigType
TLSConfig

TLS/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 mTLS
  • require_client_cert::Bool: Whether to require client certificates
  • min_version::Symbol: Minimum TLS version (:TLSv1_2 or :TLSv1_3)
  • alpn_protocols::Vector{String}: Ordered ALPN protocol preference list (default ["h2"])
  • handshake_timeout_ns::Int64: Optional per-handshake timeout in nanoseconds; 0 leaves 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"],)
source
gRPCServer.ServerStatusModule
ServerStatus

Represents the lifecycle state of a gRPC server.

States

  • STOPPED: Server is not running
  • STARTING: Server is binding to address
  • RUNNING: Server is accepting connections
  • DRAINING: Server is completing in-flight requests
  • STOPPING: Server is releasing resources
source

Context Types

gRPCServer.ServerContextType
ServerContext

Request-scoped context provided to handler functions.

Fields

  • request_id::UUID: Unique identifier for this request
  • method::String: Full method path (e.g., "/helloworld.Greeter/SayHello")
  • authority::String: Authority from :authority pseudo-header
  • metadata::Dict{String, Union{String, Vector{UInt8}}}: Request metadata
  • response_headers::Dict{String, Union{String, Vector{UInt8}}}: Response headers to send
  • trailers::Dict{String, Union{String, Vector{UInt8}}}: Trailing metadata to send
  • deadline::Union{DateTime, Nothing}: Request deadline (nothing = no deadline). The server does not interrupt a handler when the deadline passes — it is enforced only before dispatch (fail-fast) and after the handler returns (see ServerConfig deadline semantics); handlers should check remaining_time/is_cancelled cooperatively to bound their own runtime.
  • cancelled::Bool: Whether the request has been cancelled
  • peer::PeerInfo: Client connection information
  • trace_context::Union{Vector{UInt8}, Nothing}: Distributed tracing context
  • payload::Any: Arbitrary server-side payload (unused by the transport)

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)!")end
source
gRPCServer.PeerInfoType
PeerInfo

Client connection information.

Fields

  • address::Union{IPv4, IPv6}: Client IP address
  • port::Int: Client port
  • certificate::Union{Vector{UInt8}, Nothing}: Client certificate for mTLS (DER-encoded)

Example

peer = ctx.peer@info "Client connected from $(peer.address):$(peer.port)"
source

Service Registration

gRPCServer.ServiceDescriptorType
ServiceDescriptor

Describes a gRPC service and its methods.

Fields

  • name::String: Fully-qualified service name (e.g., "helloworld.Greeter")
  • methods::Dict{String, MethodDescriptor}: Methods keyed by name
  • file_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)
source
gRPCServer.MethodDescriptorType
MethodDescriptor

Describes a single RPC method.

Fields

  • name::String: Method name (e.g., "SayHello")
  • method_type::MethodType.T: RPC pattern type
  • input_type::String: Fully-qualified request message type name
  • output_type::String: Fully-qualified response message type name
  • handler::Function: Handler function reference
  • raw_request::Bool: Treat the request payload as raw protobuf bytes (skip the type registry / ProtoBuf decode; the handler receives a fresh copy of the raw bytes). Default false.
  • raw_response::Bool: Treat the handler's AbstractVector{UInt8} return value as raw protobuf bytes and pass them through verbatim (no ProtoBuf encode). Default false.

Handler Signatures by MethodType

  • UNARY: (ctx::ServerContext, request::T) -> R
  • SERVER_STREAMING: (ctx::ServerContext, request::T, stream::ServerStream{R}) -> Nothing
  • CLIENT_STREAMING: (ctx::ServerContext, stream::ClientStream{T}) -> R
  • BIDI_STREAMING: (ctx::ServerContext, stream::BidiStream{T,R}) -> Nothing

Example

method = MethodDescriptor(    "SayHello",    MethodType.UNARY,    "helloworld.HelloRequest",    "helloworld.HelloReply",    say_hello)
source
gRPCServer.MethodTypeModule
MethodType

Classifies RPC method patterns.

Values

  • UNARY: Single request, single response
  • SERVER_STREAMING: Single request, multiple responses
  • CLIENT_STREAMING: Multiple requests, single response
  • BIDI_STREAMING: Multiple requests, multiple responses
source
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.

source
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 with
  • service: A service implementation

Throws

  • InvalidServerStateError: If server is not in STOPPED state
  • ServiceAlreadyRegisteredError: If service is already registered

Example

server = GRPCServer("0.0.0.0", 50051)register!(server, GreeterService())
source
gRPCServer.register_method!Function
register_method!(registry::ServiceRegistry, service_name::String, method::MethodDescriptor)

Register a single method under service_name, creating the service entry (and its ServiceDescriptor) on first use. Unlike register! (which throws ServiceAlreadyRegisteredError if the service exists), repeated calls accumulate methods onto the same service — this is the primitive the generated per-RPC registration functions build on. The handler shape is validated at registration time (see _validate_method_handler!) and the method's Julia types are auto-registered in the type registry.

source
register_method!(dispatcher::RequestDispatcher, service_name::String, method::MethodDescriptor)

Register a single method with the dispatcher (see register_method!(::ServiceRegistry, ...)).

source
gRPCServer.servicesFunction
services(server::GRPCServer) -> Vector{String}

Get a list of registered service names.

Example

for service_name in services(server)    println(service_name)end
source
gRPCServer.service_descriptorFunction
service_descriptor(service) -> ServiceDescriptor

Get the service descriptor for a service implementation.

This function should be overloaded for custom service types.

Example

struct GreeterService endfunction gRPCServer.service_descriptor(::GreeterService)    ServiceDescriptor(        "helloworld.Greeter",        Dict(            "SayHello" => MethodDescriptor(                "SayHello", MethodType.UNARY,                "helloworld.HelloRequest", "helloworld.HelloReply",                say_hello            )        ),        nothing    )end
source

The generated register_<Service>_<Rpc>! functions build a MethodDescriptor for each RPC and call register_method! on the server's dispatcher; use the generated functions for normal services. The types and functions below are the underlying runtime interface the codegen sits on.

Registration-time validation is performed by internal helpers:

gRPCServer._validate_method_handler!Function
_validate_method_handler!(method::MethodDescriptor)

Check at registration time that method.handler is callable with the signature its MethodType requires (see _expected_handler_tuple), so mismatched handler shapes fail with a clear ArgumentError at register_! rather than a MethodError on the first call. Untyped/vararg handlers pass; wrong arity, wrong argument types, and raw/typed mismatches are rejected. Return types cannot be checked generically and are not validated.

source
gRPCServer._expected_handler_tupleFunction
_expected_handler_tuple(method::MethodDescriptor) -> Union{Tuple, Nothing}

The call tuple a handler for method must accept, derived from its MethodType and its Julia input/output types. Raw sides substitute Vector{UInt8} (the raw payload). Returns nothing when the descriptor carries no Julia types (string-typed descriptors) and cannot be shape-checked.

MethodTypeExpected handler tuple
UNARYTuple{ServerContext, ReqT}
SERVER_STREAMINGTuple{ServerContext, ReqT, ServerStream{RespT}}
CLIENT_STREAMINGTuple{ServerContext, ClientStream{ReqT}}
BIDI_STREAMINGTuple{ServerContext, BidiStream{ReqT, RespT}}
source

Stream Types

gRPCServer.ServerStreamType
ServerStream{T}

Outgoing stream for server streaming and bidirectional RPCs.

Type parameter T is the response message type.

Methods

  • send!(stream, message): Send a message
  • close!(stream): End the stream

Example

function list_features(ctx::ServerContext, request::Rectangle, stream::ServerStream{Feature})    for feature in find_features(request)        send!(stream, feature)    endend
source
gRPCServer.ClientStreamType
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)end
source
gRPCServer.BidiStreamType
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)    endend
source
gRPCServer.send!Function
send!(stream::ServerStream{T}, message::T) where T
send!(stream::ServerStream{T}, message::T; compress::Bool=true) where T

Send a message on the server stream.

Arguments

  • stream::ServerStream{T}: The stream to send on
  • message::T: The message to send
  • compress::Bool=true: Whether to compress the message (if compression is negotiated)

Throws

  • StreamCancelledError: If the stream has been cancelled
  • ArgumentError: If the stream is closed

Example

send!(stream, Feature(name="Feature 1", location=Point(latitude=1, longitude=2)))
source
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))
source

Error Handling

gRPCServer.StatusCodeModule
StatusCode

Standard gRPC status codes per specification.

Status Codes

  • OK (0): Not an error; returned on success
  • CANCELLED (1): Operation was cancelled
  • UNKNOWN (2): Unknown error
  • INVALID_ARGUMENT (3): Invalid argument provided
  • DEADLINE_EXCEEDED (4): Deadline expired before completion
  • NOT_FOUND (5): Requested entity not found
  • ALREADY_EXISTS (6): Entity already exists
  • PERMISSION_DENIED (7): Permission denied
  • RESOURCE_EXHAUSTED (8): Resource exhausted
  • FAILED_PRECONDITION (9): Precondition check failed
  • ABORTED (10): Operation aborted
  • OUT_OF_RANGE (11): Value out of range
  • UNIMPLEMENTED (12): Operation not implemented
  • INTERNAL (13): Internal error
  • UNAVAILABLE (14): Service unavailable
  • DATA_LOSS (15): Data loss or corruption
  • UNAUTHENTICATED (16): Request not authenticated
source
gRPCServer.GRPCErrorType
GRPCError <: Exception

Exception type for gRPC errors with status code, message, and optional details.

Fields

  • code::StatusCode.T: The gRPC status code
  • message::String: Human-readable error message
  • details::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"))
source
gRPCServer.BindErrorType
BindError <: Exception

Exception thrown when the server fails to bind to the configured address.

Fields

  • message::String: Description of the bind failure
  • cause::Union{Exception, Nothing}: Underlying exception if available
source
gRPCServer.ServiceAlreadyRegisteredErrorType
ServiceAlreadyRegisteredError <: Exception

Exception thrown when attempting to register a service with a name that already exists.

Fields

  • service_name::String: The duplicate service name
source
gRPCServer.InvalidServerStateErrorType
InvalidServerStateError <: Exception

Exception thrown when an operation is attempted in an invalid server state.

Fields

  • expected::ServerStatus.T: The expected server state
  • actual::ServerStatus.T: The actual server state
source
gRPCServer.MethodSignatureErrorType
MethodSignatureError <: Exception

Exception thrown when a handler method has an invalid signature.

Fields

  • method_name::String: The method with invalid signature
  • expected::String: Description of expected signature
  • actual::String: Description of actual signature
source
gRPCServer.StreamCancelledErrorType
StreamCancelledError <: Exception

Exception thrown when a stream operation is attempted on a cancelled stream.

Fields

  • reason::String: The reason for cancellation
source
gRPCServer.UnsupportedFeatureErrorType
UnsupportedFeatureError <: Exception

Exception thrown when a feature is explicitly requested that the selected HTTP/2 backend does not support.

Fields

  • feature::Symbol: The feature (configuration keyword) that is unsupported
  • backend::Type: The backend type that does not support the feature
  • message::String: Human-readable explanation, including the way out
source
gRPCServer.http2_to_grpc_statusFunction
http2_to_grpc_status(http2_error_code::UInt32) -> StatusCode.T

Map 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 → CANCELLED
source
http2_to_grpc_status(http2_error_code::Integer) -> StatusCode.T

Convenience method accepting any integer type.

source

Interceptors

gRPCServer.InterceptorType
Interceptor

Abstract 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) -> response

Arguments

  • ctx::ServerContext: Request context
  • request_or_stream: Request message (unary/server streaming) or stream (client/bidi streaming)
  • info::MethodInfo: Method information
  • next::Function: Next handler in the chain (call to continue processing)

Example

struct AuthInterceptor <: Interceptor    required_scope::Stringendfunction (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)end
source
gRPCServer.MethodInfoType
MethodInfo

Information 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 endfunction (::LoggingInterceptor)(ctx, request, info::MethodInfo, next)    @info "Calling" service=info.service_name method=info.method_name    return next(ctx, request)end
source
gRPCServer.LoggingInterceptorType
LoggingInterceptor <: Interceptor

Built-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())
source
gRPCServer.MetricsInterceptorType
MetricsInterceptor <: Interceptor

Built-in interceptor that collects request metrics.

Fields

  • on_request::Function: Called with (method, request_size) on each request
  • on_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)
source
gRPCServer.TimeoutInterceptorType
TimeoutInterceptor <: Interceptor

Built-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 default
source
gRPCServer.RecoveryInterceptorType
RecoveryInterceptor <: Interceptor

Built-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))
source
gRPCServer.add_interceptor!Function
add_interceptor!(dispatcher::RequestDispatcher, interceptor::Interceptor)

Add a global interceptor.

source
add_interceptor!(dispatcher::RequestDispatcher, service_name::String, interceptor::Interceptor)

Add a service-specific interceptor.

source
add_interceptor!(server::GRPCServer, interceptor::Interceptor)

Add a global interceptor that applies to all services.

Example

add_interceptor!(server, LoggingInterceptor())add_interceptor!(server, MetricsInterceptor())
source
add_interceptor!(server::GRPCServer, service_name::String, interceptor::Interceptor)

Add an interceptor for a specific service.

Example

add_interceptor!(server, "helloworld.Greeter", AuthInterceptor())
source

Health Checking

gRPCServer.HealthStatusModule
HealthStatus

Service health state for the health checking service.

Values

  • UNKNOWN: Health status is unknown
  • SERVING: Service is healthy and accepting requests
  • NOT_SERVING: Service is not healthy
  • SERVICE_UNKNOWN: Service is not registered
source
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 maintenance
source
set_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)
source
gRPCServer.get_healthFunction
get_health(server::GRPCServer, service_name::String="") -> HealthStatus.T

Get the health status for a service (or overall server if empty string).

source

Reflection Support

gRPCServer.HEALTH_DESCRIPTORConstant
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

source
gRPCServer.REFLECTION_DESCRIPTORConstant
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

source

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 state
  • BindError: If the server cannot bind to the address

Example

start!(server)# Server is now running in background
source
gRPCServer.stop!Function
stop!(server::GRPCServer; force::Bool=false, timeout::Float64=0.0)

Stop the server.

Arguments

  • server::GRPCServer: The server to stop
  • force::Bool=false: If true, immediately close all connections
  • timeout::Float64=0.0: Override drain timeout (0 = use config)

Throws

  • InvalidServerStateError: If server is not running

Example

stop!(server)  # Graceful shutdownstop!(server; force=true)  # Immediate shutdown
source

TLS

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 running
  • ArgumentError: If TLS is not configured

Example

reload_tls!(server)  # Reload certificates
source

Context Operations

gRPCServer.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])
source
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")
source
gRPCServer.get_metadataFunction
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"))end
source
gRPCServer.remaining_timeFunction
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"))end
source

cancel! is not exported — call it as gRPCServer.cancel!(ctx).

Compression

gRPCServer.CompressionCodecModule
CompressionCodec

Supported compression algorithms for gRPC messages.

Values

  • IDENTITY: No compression
  • GZIP: Gzip compression
  • DEFLATE: Deflate compression
source
gRPCServer.compressFunction
compress(data::Vector{UInt8}, codec::CompressionCodec.T) -> Vector{UInt8}

Compress data using the specified codec.

source
gRPCServer.decompressFunction
decompress(data::Vector{UInt8}, codec::CompressionCodec.T) -> Vector{UInt8}

Decompress data using the specified codec.

source
gRPCServer.codec_nameFunction
codec_name(codec::CompressionCodec.T) -> String

Get the gRPC encoding name for a compression codec.

source
gRPCServer.parse_codecFunction
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.

source
gRPCServer.negotiate_compressionFunction
negotiate_compression(
    client_encodings::Vector{CompressionCodec.T},
    server_codecs::Vector{CompressionCodec.T}
) -> CompressionCodec.T

Negotiate compression codec between client and server. Returns the first codec supported by both, preferring client order. Falls back to IDENTITY if no common codec.

source

ProtoBuf Code Generation

Loading gRPCServer registers its ProtoBuf.jl code generation handler; one protojl run (with gRPCClient.jl loaded too) emits message types, client stubs, and per-service registration functions in a single generated file. protojl is re-exported from ProtoBuf.jl by gRPCServer. See Code Generation for the full walkthrough.

gRPCServer.grpc_register_service_codegenFunction
grpc_register_service_codegen()

Register gRPCServer's external code generation handler with ProtoBuf.jl so that a subsequent protojl run emits server descriptors (<Service>_<Rpc>_Method builders, register_<Service>_<Rpc>! registration functions, and a register_<Service>! aggregate) for each service in the .proto.

This is called automatically from the module's __init__, so it normally does not need to be invoked directly. It can be called explicitly (e.g. gRPCServer.grpc_register_service_codegen()) to re-register the handler after ProtoBuf.jl has been reloaded.

source

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.AbstractHTTP2BackendType
AbstractHTTP2Backend

Abstract type representing an HTTP/2 backend for gRPCServer.jl.

Backends drive the server through one of two contracts:

  1. serve_grpc (primary): the backend owns its listener/serve loop and presents each incoming call as an AbstractGRPCStream to dispatch_grpc_call. See serve_grpc, uses_serve_grpc, and stop_serving!. All three built-in backends use this contract.
  2. create_connection (legacy): the backend implements create_connection to return an HTTP/2 connection object driven by gRPCServer's own frame loop. Kept for custom backends written against the old interface; the connection object must be compatible with PureHTTP2.jl's HTTP2Connection interface (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.

source
gRPCServer.PureHTTP2BackendType
PureHTTP2Backend <: AbstractHTTP2Backend

Opt-in pure-Julia HTTP/2 backend using PureHTTP2.jl (the default backend is HTTPjlBackend; pass http2_backend=PureHTTP2Backend() to the GRPCServer constructor to select it).

PureHTTP2 is an optional dependency. Load it before constructing the backend:

using gRPCServer, PureHTTP2server = GRPCServer("127.0.0.1", 50051; http2_backend = PureHTTP2Backend())

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.

source
gRPCServer.create_connectionFunction
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).

This is the legacy custom-backend contract. New backends should implement serve_grpc instead; the built-in backends all do. PureHTTP2Backend implements create_connection inside the PureHTTP2 extension.

Examples

backend = PureHTTP2Backend()conn = create_connection(backend)  # Returns a PureHTTP2.HTTP2Connection
source
gRPCServer.HTTPjlBackendType
HTTPjlBackend <: AbstractHTTP2Backend

HTTP/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 live TLS certificate reload (reload_tls!); HTTP.jl owns the TLS context.

Select PureHTTP2Backend() if you need certificate reload.

source
gRPCServer.Nghttp2BackendType
Nghttp2Backend <: AbstractHTTP2Backend

HTTP/2 backend backed by the nghttp2 C library through Nghttp2Wrapper.jl.

Nghttp2Wrapper is an optional dependency. Load it before constructing the backend:

using gRPCServer, Nghttp2Wrapperserver = 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.

source
gRPCServer.BackendCapabilitiesType
BackendCapabilities

Declares which features an HTTP/2 backend supports. Every field defaults to true; a backend declares false for the features it cannot honor. Custom backends get the all-true default unless they define backend_capabilities for their type.

Fields (all Bool)

  • tls: TLS cert/key
  • tls_mtls: mutual TLS (client_ca, require_client_cert)
  • tls_min_version: minimum TLS version selection
  • tls_alpn: ALPN protocol list
  • tls_handshake_timeout: per-handshake timeout
  • tls_reload: reload_tls!
  • max_connections: max_connections config
  • max_concurrent_streams: max_concurrent_streams config
  • queued_requests: max_queued_requests config
  • keepalive: keepalive_interval / keepalive_timeout config
  • connection_timeouts: idle_timeout / read_header_timeout / read_timeout / write_timeout
  • listener_knobs: max_header_bytes / reuseaddr / backlog
  • http2_settings: h2_initial_window_size / h2_connection_window_size
  • drain_timeout_config: drain_timeout config field (vs. stop!(; timeout=))
  • receive_cap: max_receive_message_length enforcement
  • decompression: receive-side decompression (informational)
  • send_compression: send-side compression (compression_enabled / compression_threshold / supported_codecs)
  • server_streaming: server-streaming RPCs (informational)
  • bidi_streaming: bidi-streaming RPCs (informational)
  • reflection: the reflection service (enable_reflection)
  • health: the health service (enable_health_check)
source
gRPCServer.backend_capabilitiesFunction
backend_capabilities(backend) -> BackendCapabilities

Return the capability declaration for a backend type (or instance). Custom backends default to all-true; built-in backends declare the features they cannot honor. Keyed on the type, so backend_capabilities(Nghttp2Backend) works even when the Nghttp2Wrapper extension is not loaded.

source
gRPCServer.backend_defaultsFunction
backend_defaults(backend) -> NamedTuple

Per-backend default values for the GRPCServer configuration keywords. The default implementation derives the values from a fresh ServerConfig() (single source of truth — no duplicated literals), plus the two h2-window keywords that are GRPCServer-level (65535 = the HTTP.jl HTTP2Settings defaults). A backend may override this method to declare genuinely different effective defaults; for the built-in backends the values are identical today, and the per-backend difference (what raises when explicitly set) lives in backend_capabilities.

source
gRPCServer.GRPCServerHTTPJlFunction
GRPCServerHTTPJl(host, port; kwargs...) -> GRPCServer

Create a gRPC server on the HTTP.jl backend (HTTPjlBackend).

Accepts the same configuration keywords as GRPCServer; the backend is fixed to HTTPjlBackend. Explicitly setting a keyword this backend cannot honor raises UnsupportedFeatureError at construction. On this backend the following keywords raise (explicitly set): max_connections, max_queued_requests, keepalive_interval, keepalive_timeout, drain_timeout (pass timeout= to stop! instead), compression_enabled=true, compression_threshold, supported_codecs; reload_tls! also raises on this backend. max_concurrent_streams is supported (default 100, enforced per connection by HTTP.jl).

Example

server = GRPCServerHTTPJl("0.0.0.0", 50051; max_receive_message_length=8 * 1024 * 1024)
source
gRPCServer.GRPCServerPureHTTP2Function
GRPCServerPureHTTP2(host, port; kwargs...) -> GRPCServer

Create a gRPC server on the pure-Julia HTTP/2 backend (PureHTTP2Backend).

PureHTTP2 is an optional dependency: load it before constructing the server (via using PureHTTP2, which also loads the gRPCServerPureHTTP2Ext extension), or constructing this entry point throws an actionable ArgumentError.

Accepts the same configuration keywords as GRPCServer; the backend is fixed to PureHTTP2Backend. Explicitly setting a keyword this backend cannot honor raises UnsupportedFeatureError at construction. On this backend the following keywords raise (explicitly set): max_connections, max_concurrent_streams, max_queued_requests, keepalive_interval, keepalive_timeout, idle_timeout, read_header_timeout, read_timeout, write_timeout, max_header_bytes, reuseaddr, backlog, h2_initial_window_size, h2_connection_window_size, max_receive_message_length, compression_enabled=true, compression_threshold, supported_codecs. drain_timeout is supported.

Example

using PureHTTP2server = GRPCServerPureHTTP2("0.0.0.0", 50051; drain_timeout=60.0)
source
gRPCServer.GRPCServerNghttp2Function
GRPCServerNghttp2(host, port; kwargs...) -> GRPCServer

Create a gRPC server on the Nghttp2 backend (Nghttp2Backend).

Accepts the same configuration keywords as GRPCServer; the backend is fixed to Nghttp2Backend. Requires the Nghttp2Wrapper extension to be loaded (otherwise constructing Nghttp2Backend throws). Explicitly setting a keyword this backend cannot honor raises UnsupportedFeatureError at construction: TLS is supported (cert/key only — mTLS, min_version, alpn_protocols, handshake_timeout_ns raise), enable_health_check is supported (Check works; Watch is refused per-request), and everything else configurable raises when explicitly set (enable_reflection, the timeouts, listener knobs, h2 windows, keepalive, connection limits, message-length limits, and send-side compression).

source

Raised stream-handler contract (all built-in backends)

The preferred contract, higher-level than the connection factory: the backend owns its listener and serve loop, and presents each gRPC call as an AbstractGRPCStream. It was introduced for the HTTP.jl backend; as of 1.0 all three built-in backends (HTTPjl, PureHTTP2, nghttp2) serve through it, with the HTTP.jl request path driving dispatch via serve_grpc.

gRPCServer.AbstractGRPCStreamType
AbstractGRPCStream

Represents 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, grpc_method, request_metadata, read_message!, is_cancelled, send_response_headers!, send_message!, send_trailers!, and reset!.

source
gRPCServer.serve_grpcFunction
serve_grpc(backend::AbstractHTTP2Backend, server, on_call) -> Nothing

Own 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.

source

HTTP/2 Stream State

These functions are used for advanced stream state management, particularly for handling edge cases with client disconnection. As of 1.0 they come from PureHTTP2.jl directly — gRPCServer no longer re-exports them (PureHTTP2 became an optional weak dependency). Load PureHTTP2 and qualify: PureHTTP2.can_send(stream), PureHTTP2.StreamError.

  • can_send(stream) — check whether a stream is in a state that accepts outbound data
  • StreamError — exception type for HTTP/2 stream-level errors