Packages
phoenix_gen_api
2.19.0
2.22.0
2.21.1
2.21.0
2.20.1
2.20.0
2.19.0
2.18.1
2.18.0
2.17.1
2.17.0
2.16.0
2.15.0
2.14.0
2.13.0
2.12.0
2.11.0
2.10.0
2.9.1
2.9.0
2.8.0
2.7.0
2.6.1
2.6.0
2.5.0
2.4.0
2.3.0
2.2.0
2.1.1
2.1.0
2.0.1
2.0.0
1.2.0
1.1.3
1.1.2
1.1.1
1.1.0
1.0.1
1.0.0
0.2.1
0.2.0
0.1.1
0.1.0
0.0.16
0.0.15
0.0.14
0.0.13
0.0.12
0.0.11
0.0.10
0.0.9
0.0.8
0.0.7
0.0.6
0.0.5
0.0.4
0.0.3
0.0.2
0.0.1
A library for fast develop APIs in Elixir cluster, using Phoenix Channels for transport data, auto pull api configs from service nodes.
Current section
Files
Jump to
Current section
Files
phoenix_gen_api
README.md
README.md
[](https://hexdocs.pm/phoenix_gen_api)
[](https://hex.pm/packages/phoenix_gen_api)
# PhoenixGenApi
A framework for rapidly building backend APIs on top of Phoenix Channels and Erlang clustering. Define your business logic on any node — the framework handles routing, validation, permissions, retries, and observability. No HTTP endpoints to write, no routes to configure, no restarts to deploy.
**Version**: 2.18.0 | **Elixir**: ~> 1.18 | **OTP**: ~> 27 | **License**: MPL-2.0
## Why PhoenixGenApi?
Traditional Phoenix backends require you to: define routes, write controllers, serialize responses, handle errors, and restart to deploy changes. PhoenixGenApi eliminates all of that:
- **No routes, no controllers** — Clients call functions by name over WebSocket. The framework routes requests to the right node automatically.
- **No restarts to deploy** — Register new APIs at runtime from any cluster node. The gateway picks them up instantly (push) or on the next pull interval.
- **Built-in cross-cutting concerns** — Permissions, rate limiting, retries, circuit breakers, hooks, and telemetry come standard. No plugs, no middleware.
- **Multi-node by default** — Erlang distribution means your APIs run across the cluster. The framework handles node selection, RPC, and failover.
- **Real-time ready** — Async responses, streaming, and relay messages (group chat) are first-class features, not afterthoughts.
## How It Works
```text
┌──────────┐ WebSocket ┌──────────────────┐ RPC ┌──────────────┐
│ Client │ ◄──────────────► │ Phoenix Gateway │ ◄─────────► │ Service Node │
└──────────┘ (Phoenix Ch.) │ (uses this lib) │ (Erlang) │ (your app) │
└──────────────────┘ └──────────────┘
```
1. **Clients** send requests through a Phoenix Channel.
2. The **Gateway** looks up the matching `FunConfig`, selects a node, validates arguments & permissions, then executes the remote function.
3. The **Service Node** runs the function and returns the result.
Service nodes can register new APIs at any time — the gateway picks them up automatically (pull) or receives them immediately (push).
## Features
| Feature | Description |
|---------|-------------|
| **Dynamic Configuration** | Add, update, or remove APIs at runtime from any cluster node |
| **Response Modes** | Sync, async, streaming, and fire-and-forget |
| **Node Selection** | Random, hash-based, round-robin, sticky, or custom strategies |
| **Function Versioning** | Run multiple API versions side-by-side; enable/disable per version |
| **Rate Limiting** | Sliding-window rate limiter with global and per-API limits |
| **Permissions** | Authenticated-only, argument-based, role-based, or custom callback |
| **Retry** | Configurable retry on same node or across all nodes, with exhaustion telemetry |
| **Hooks** | `before_execute` / `after_execute` callbacks with per-hook timeout protection |
| **Relay Messages** | Group-based message relaying with automatic cleanup on disconnect |
| **Circuit Breaker** | Pool-level and worker-level circuit breakers |
| **Telemetry** | 31 events across 5 categories for observability |
| **Security** | Admin gate, push tokens, MFA allowlist, payload size limits |
## Installation
```elixir
def deps do
[
{:phoenix_gen_api, "~> 2.16"}
]
end
```
Use [`:libcluster`](https://hex.pm/packages/libcluster) to form the Erlang cluster.
## Documentation
| Guide | Description |
|---|---|
| [Getting Started](guides/getting_started.md) | Build a working API gateway in 10 minutes with a Phoenix gateway and service node |
| [Step-by-Step Guide](guides/step_by_step_guide.md) | Every feature explained with copy-paste code examples: validation, permissions, rate limiting, async, streaming, hooks, relay, security, telemetry |
| [FunConfig Reference](guides/fun_config.md) | Field-by-field reference for the central configuration struct |
| [Configuration](guides/configuration.md) | Full configuration reference: gateway, rate limiter, worker pool, security |
| [Architecture](guides/architecture.md) | Deep dive into the supervision tree, request lifecycle, config management, execution engine, and all subsystems |
| [Execute Flow](guides/execute_flow.md) | Line-by-line walkthrough of the complete request execution path with file references |
| [Relay Messages](guides/relay_messages.md) | Complete reference for group-based messaging: group types, permission matrix, process monitoring |
| [Telemetry](guides/telemetry.md) | Full event reference, integration patterns, Telemetry.Metrics examples, and best practices |
## Quick Start
Define your API on the service node:
```elixir
defmodule MyApp.Api do
def get_user(user_id) do
%{id: user_id, name: "Alice"}
end
end
```
Create a `FunConfig` and register it on the gateway (pull mode):
```elixir
# On the service node — define a supporter
defmodule MyApp.GenApi.Supporter do
def get_config(_arg) do
{:ok, [%PhoenixGenApi.Structs.FunConfig{
request_type: "get_user",
service: "user_service",
nodes: [Node.self()],
mfa: {MyApp.Api, :get_user, []},
arg_types: %{"user_id" => :string},
response_type: :sync
}]}
end
end
# On the gateway — configure the puller
config :phoenix_gen_api, :gen_api,
service_configs: [%{
service: "user_service",
nodes: [:"app@host"],
module: MyApp.GenApi.Supporter,
function: :get_config,
args: []
}]
```
Add PhoenixGenApi to your Channel:
```elixir
defmodule MyAppWeb.ApiChannel do
use Phoenix.Channel
use PhoenixGenApi, event: "api"
end
```
Call from the client:
```json
{
"service": "user_service",
"request_type": "get_user",
"request_id": "req_1",
"args": { "user_id": "123" }
}
```
That's it — you have a working API gateway. See the [Getting Started](guides/getting_started.md) guide for the full 2-node walkthrough.
## IEx Helpers
```elixir
PhoenixGenApi.rl_status("user_123") # Rate limit status
PhoenixGenApi.rl_global() # Global rate limits
PhoenixGenApi.rl_config() # Rate limiter config
PhoenixGenApi.cache_status() # Config cache status
PhoenixGenApi.pool_status() # Worker pool status
PhoenixGenApi.pushed_services_status() # Pushed services status
```
## Related Packages
| Package | Description |
|---|---|
| [PhoenixGenApi](https://hex.pm/packages/phoenix_gen_api) | Core library — dynamic API gateway over Phoenix Channels |
| [EasyRpc](https://hex.pm/packages/easy_rpc) | Wrap RPC calls from remote nodes so they can be used like local functions |
| [ClusterHelper](https://hex.pm/packages/cluster_helper) | Dynamic cluster node discovery |
| [ToonEx](https://hex.pm/packages/toon_ex) | TOON encoder/decoder — compact binary protocol for Phoenix Channels |
| [AshPhoenixGenApi](https://hex.pm/packages/ash_phoenix_gen_api) | Ash extension that auto-generates `FunConfig` from Ash resources |
## AI Agent Support
```bash
mix usage_rules.sync AGENTS.md --all --link-to-folder deps --inline usage_rules:all
mix tidewave
```
Connect at `http://localhost:4114/tidewave/mcp`. See [Tidewave](https://hexdocs.pm/tidewave/) for details.