Skip to main content

CHANGELOG.md

# Changelog

All notable changes to this project are documented here. The format is
based on Keep a Changelog, and this project adheres to Semantic
Versioning.

## [Unreleased]

## [0.1.0] - 2026-06-13

First release. gRPC for Erlang on the livery HTTP/2 stack: server and
client, all four call types, and the surrounding ecosystem.

### Added
- Project scaffold: OTP application, supervisor, build pipeline with
  `gpb` and `rebar3_gpb_plugin`, sample `helloworld.proto`.
- Wire layer: `livery_grpc_frame` (length-prefixed framing + streaming
  decoder), `livery_grpc_status` (canonical codes, grpc-message
  encoding, trailers), `livery_grpc_compression` (identity + gzip),
  `livery_grpc_codec` (gpb glue + content-type checks). Property and unit
  tests.
- `livery_grpc_service`: method descriptors derived from gpb
  introspection (wire path, message types, call kind, snake_case callback
  name) and a path-keyed routing index.
- Server: `livery_grpc:start_server/1` runs gRPC on a dedicated h2
  listener; `livery_grpc_server` dispatches `POST /pkg.Svc/Method` to the
  bound callback module. Unary and server-streaming, with status in
  trailers (and Trailers-Only for pre-dispatch errors). End-to-end tests
  over h2c cover success, error status, handler crash, unknown method,
  and streaming.
- Client: `livery_grpc_client` calls gRPC services over the h2 client
  (unary and server-streaming), with metadata and gzip. `livery_grpc_wire`
  centralises message encode/decode for both sides. In-tree client tests
  cover unary, error status, server-streaming, and gzip both directions.
- Cross-cutting: `grpc-timeout` deadlines (client sends and bounds the
  wait; server parses, exposes in the context, and aborts a unary handler
  that overruns), error details via `grpc-status-details-bin`, request
  metadata, and livery middleware as gRPC interceptors.
- Health: the standard `grpc.health.v1.Health` service
  (`livery_grpc_health:service/0`), with per-service serving status.
  `Check` is unary; `Watch` emits the current status once (live updates
  follow the bidirectional work).
- gRPC-Web: `livery_grpc_web` framing on the same server (binary and
  text), with the status delivered as an in-body trailer frame. Unary and
  server-streaming. Reflection is deferred: its RPC is bidirectional and
  waits on the h2 bidi work.
- Example (`greeter_example`), a quickstart guide, and a `grpcurl` interop
  smoke test (`make interop`) confirming on-the-wire compliance with an
  external gRPC client.
- Client-streaming and bidirectional streaming on both sides, on h2
  0.10.0. The server reads requests through a `livery_grpc_stream` handle
  and interleaves replies in the chunked producer; the client adds
  `client_stream/3,4` and `open/2,3` + `send/2` + `send_end/1` +
  `recv/1,2`. All four call types are verified against grpcurl.
- Client interceptor stack, the outbound twin of livery's server
  middleware: `interceptors` on `connect/3` or per call, with `before/1`,
  `after_response/1`, and `wrap/1`, matching the `livery_client` layer
  shape (Tower layers on the BEAM).
- Server reflection (`grpc.reflection.v1`): enable with `reflection =>
  true` and tools like grpcurl discover services and message schemas at
  runtime, with no local `.proto`. Verified with grpcurl `list`,
  `describe`, and a fully reflective call.
- Health `Watch` now streams live updates: it emits the current status and
  a new message on every change until the client disconnects, backed by a
  small subscription store (`livery_grpc_health_store`).
- Code generation (`livery_grpc_codegen`, `make stubs`): per service, an
  `erpc`-style client stub (`greeter_client:say_hello/2`) and a service
  behaviour (`-behaviour(greeter_service)`) for compiler-checked handlers.

### Changed
- Servers are now owned by a supervised process (`livery_grpc_listener`
  under `livery_grpc_server_sup`) instead of the caller, so a server
  started from a short-lived process keeps running. `start_server/1`
  returns the listener owner pid.

### Added (testing)
- `livery_grpc_e2e_SUITE`, a Common Test end-to-end suite against a real
  running server: the full journey with the in-tree client, and the same
  calls driven by grpcurl over reflection (skipped if grpcurl is absent).

### Added (docs and example)
- A documentation set in the style of grpc.io with Erlang snippets:
  Introduction, Core concepts, Getting started, a Basics tutorial built on
  a real RouteGuide example, a Design guide for the Erlang integration, an
  Erlang-integration how-to, and task-oriented guides modeled on the gRPC
  guides (streaming, metadata, interceptors, deadlines, cancellation,
  error handling, status codes, compression, authentication, health,
  reflection, retry, graceful shutdown, flow control, wait-for-ready,
  gRPC-Web, generated stubs, testing). All wired into ex_doc.
- `examples/route_guide.erl` + `proto/route_guide.proto`: the RouteGuide
  example, exercising all four call types, with an eunit suite.
- `livery_grpc_client:cancel/1` cancels a streaming call.