-
Notifications
You must be signed in to change notification settings - Fork 4
Description
Support for path prefixes to mount multiple OpenAPI specs on a single port
Problem
Currently, each erf:start_link/1 call creates an independent HTTP server bound to a specific port. This means that if you have multiple OpenAPI specifications, you must run each one on a separate port:
%% API 1 on port 8081
erf:start_link(#{
name => users_api,
port => 8081,
spec_path => <<"users.openapi.json">>,
...
}).
%% API 2 on port 8082
erf:start_link(#{
name => products_api,
port => 8082,
spec_path => <<"products.openapi.json">>,
...
}).This creates operational overhead and complicates deployments, especially in containerized environments where exposing multiple ports requires additional configuration.
Use Case
Organizations often have multiple bounded contexts or microservices that they want to expose through a single HTTP endpoint with path-based routing:
| Path | API |
|---|---|
https://api.example.com/users/... |
Users API |
https://api.example.com/products/... |
Products API |
https://api.example.com/orders/... |
Orders API |
Proposed Solution
Add a path_prefix configuration option that allows mounting an OpenAPI spec under a specific path prefix:
erf:start_link(#{
name => users_api,
port => 8080,
path_prefix => <<"/users">>, %% New option
spec_path => <<"users.openapi.json">>,
callback => users_callback
}).
erf:start_link(#{
name => products_api,
port => 8080, %% Same port
path_prefix => <<"/products">>,
spec_path => <<"products.openapi.json">>,
callback => products_callback
}).A request to GET /users/123 would strip the prefix and match against /123 in the users spec router.
Implementation Considerations
The change would likely involve:
-
erf.erl: Addpath_prefixto theconf()type and pass it through to router generation -
erf_router.erl: Modifygenerate/2to either:- Prepend the prefix to all path patterns in the generated clauses, or
- Strip the prefix from incoming requests before pattern matching
-
HTTP server coordination: When multiple erf instances share the same port, coordinate through a shared listener that dispatches to the correct router based on prefix matching
-
Configuration validation: Ensure no prefix conflicts exist on the same port
Benefits
- Simplified deployments: Single port exposure for multiple APIs
- Better resource utilization: Shared acceptor pool and connection handling
- Cleaner architecture: Logical grouping of related APIs under a common host
- Container-friendly: Reduces port mapping complexity in Docker/Kubernetes environments
- API gateway pattern: Enables building lightweight API gateways with erf
Alternatives Considered
| Alternative | Drawback |
|---|---|
| Manually modifying OpenAPI specs | Prepending prefixes to all paths in each spec works but is error-prone and breaks the design-first philosophy where the spec should remain the source of truth |
| External reverse proxy | Adding Nginx/HAProxy in front works but introduces additional infrastructure complexity for what could be handled natively |
| Merging specs into one | Combining multiple specs loses the benefits of separation, independent versioning, and modular callback organization |
Metadata
Metadata
Assignees
Labels
Type
Projects
Status