Skip to content

Transports Overview

Transports adapt external frameworks and brokers to Anvil SDK contracts.

Anvil remains framework-agnostic. Driver repositories carry third-party dependencies and framework-specific configuration.

github.com/TDB-Group/anvil-http/native
github.com/TDB-Group/anvil-http/std
github.com/TDB-Group/anvil-http/fiber
github.com/TDB-Group/anvil-grpc
github.com/TDB-Group/anvil-graphql
github.com/TDB-Group/anvil-queue/memory
github.com/TDB-Group/anvil-queue/redis
github.com/TDB-Group/anvil-queue/nats
github.com/TDB-Group/anvil-queue/sqs

Official drivers expose a Driver function:

app := anvil.New(
httpstd.Driver(),
)

Drivers can also expose DriverFrom for tests or custom setup:

transport := httpstd.New()
app := anvil.New(httpstd.DriverFrom(transport))

Generated wiring expects these protocol names:

Driver familyProtocol()
HTTP and WebSockethttp
GraphQLgraphql
gRPCgrpc
Queuequeue

The protocol string and SDK interface both matter. For example, a generated HTTP module resolves Protocol() == "http" and then requires sdk.HTTPTransport. WebSocket wiring looks for the first registered sdk.WebSocketTransport, which is normally the same HTTP driver.

Driver options belong to the driver:

httpfiber.Driver(fiber.Config{
DisableStartupMessage: true,
ProxyHeader: "CF-Connecting-IP",
})

Anvil does not mirror framework-specific settings.

HTTP, GraphQL, and gRPC drivers can share one listener.

Anvil runs the listener and request classification. Drivers register targets. In the normal anvil.New(...) edge path, HTTP-family drivers run behind the shared public port; Anvil calls the selected driver after classification.

An edge-target driver must implement http.Handler plus its SDK transport contract. Anvil uses that combination to decide whether the driver belongs behind the shared listener. Drivers with a different shape are started as background transports.

The native HTTP driver is the official low-overhead exception to the normal shared-edge shape. It implements a narrow listener-owner marker. Anvil gives it the public address directly only when it is the single HTTP-family transport in the app. When GraphQL or gRPC are registered too, the native driver stays behind the shared edge through its http.Handler compatibility path.

If a custom driver implements several edge contracts at once, Anvil registers it as GraphQL first, then gRPC, then HTTP. Official drivers avoid that ambiguity by exposing one edge protocol per module. WebSocket support is an HTTP-driver capability because a WebSocket route starts as an HTTP upgrade.

Classification order:

  1. gRPC: HTTP/2 request with Content-Type beginning with application/grpc.
  2. GraphQL: exact request path registered by the GraphQL driver.
  3. HTTP: fallback target when an HTTP driver is registered.

GraphQL path matching happens before HTTP fallback. The GraphQL driver handles the GraphQL request format after the edge selects it.

GraphQL selection is exact path selection, not body inspection. Driver-reported paths are normalized to begin with /, but the request path itself is matched as-is. REST over HTTP/2 still goes to the HTTP driver unless its content type marks it as gRPC.

Queue transports run as background transports because Redis, NATS, SQS, and the memory queue are broker or process consumers, not request handlers.

Drivers can still expose standalone Start and Shutdown behavior for tests and low-level integrations. That path is separate from the normal edge runtime. In the normal edge runtime, Anvil does not call Start on HTTP-family target drivers; it calls Start on the edge transport and calls driver Shutdown(ctx) through the edge when the app stops.

Read Edge Runtime for listener defaults, TLS behavior, WithListener, and the exact dispatch order.