API Configuration (api.json
)
The api.json
file lives in configs/
and is the single source of truth for your HTTP‑API surface. It defines routing, authentication, throttling, error formats, and more. On each boot, the framework reads this file in full to handle api requests.
How the API Works
All API requests are routed by sub‑domain first, then path:
https://{domain_id}.example.com/…
- DNS – Create an
A
orCNAME
record for eachdomain_id
(e.g.,api.example.com
,sandbox.example.com
) pointing at your app host. - Middleware – Register your global API middleware under the
api
alias inconfigs/middleware.php
. - Enable – Flip
"enabled"
totrue
inapi.json
; the framework mounts all routes at boot.
To summarize:
- Choose a Subdomain: set
"domain_id"
(e.g.,"api"
→api.example.com
). - DNS Records: point that domain to your server.
- Deploy: ensure your middleware stack under alias
api
is in place, then set"enabled": true
.
How to Use
The framework ships with an
api.sample.json
inconfigs/
.
cp configs/api.sample.json configs/api.json
Location Place
api.json
in theconfigs/
directory of your project.Subdomain Setup Decide on a
domain_id
(e.g.,"api"
) and create a matching subdomain (api.example.com
). Ensure SSL/TLS certs cover it.Single Source of Truth All API settings—methods, auth, rate limits, error codes, etc.—live in this file. Edits take effect on next deploy.
Customization Tweak each section below—core, access control, caching, throttling, etc.—to your needs. You can safely add new keys later without breaking existing clients.
API Configuration Overview
Below is a detailed look at each key inside the top‑level api
object.
API‑Level Keys
Input | Description | Example |
---|---|---|
enabled | Master on/off switch. false disables all API routes. | false |
domain_id | Subdomain slug—becomes https://{domain_id}.example.com | "api" |
charset | Default response encoding. | "utf-8" |
methods | Allowed HTTP verbs (array). | ["GET","POST","PUT","DELETE"] |
"api": {
"enabled": false,
"domain_id": "api",
"charset": "utf-8",
"methods": ["GET","POST","PUT","DELETE"],
...
}
Access Control
Input | Description | Example |
---|---|---|
restricted | When true , blocks unauthenticated requests by default. | true |
auth_type | Shorthand guard: "apikey" or "jwt" . | "apikey" |
"restricted": true,
"auth_type": "apikey",
Tip: To switch to JWT, set both
auth_type
andauthentication.type
to"jwt"
(and remove API‑key logic).
Caching
Input | Description | Example |
---|---|---|
cache | false = no caching, or an object when needed. | false |
"cache": false,
Rate Limiting
Input | Description | Example |
---|---|---|
rate_limit.enabled | Toggle throttling middleware. | true |
rate_limit.requests_per_minute | Steady-state cap per token/IP per minute. | 60 |
rate_limit.burst | Extra allowance for short traffic spikes. | 120 |
"rate_limit": {
"enabled": true,
"requests_per_minute": 60,
"burst": 120
},
Error Handling
Input | Description | Example |
---|---|---|
errors.expose_stack | Show stack traces in JSON (never in production). | false |
errors.default_locale | Fallback locale for error messages. | "en-US" |
errors.codes | Map internal codes → HTTP status. | { "NOT_FOUND":404 } |
"errors": {
"expose_stack": false,
"default_locale": "en-US",
"codes": {
"VALIDATION_FAILED": 400,
"NOT_FOUND": 404,
"SERVER_ERROR": 500
}
},
Authentication
Input | Description | Example |
---|---|---|
authentication.type | Driver: "apikey" or "jwt" . | "jwt" |
authentication.secret_env | Env var name for JWT secret. | "API_JWT_SECRET" |
authentication.token_ttl | JWT lifetime in seconds. | 3600 |
"authentication": {
"type": "jwt",
"secret_env": "API_JWT_SECRET",
"token_ttl": 3600
},
Authorization (RBAC)
Input | Description | Example |
---|---|---|
authorization.restricted | When true , every route goes through an RBAC check. | true |
authorization.roles | Array of valid role slugs. | ["admin","user"] |
authorization.anonymous_read | Allow unauthenticated GET s if set to true . | false |
"authorization": {
"restricted": true,
"roles": ["admin","user"],
"anonymous_read": false
}
Example api.json
{
"api": {
"enabled": false,
"domain_id": "api",
"charset": "utf-8",
"methods": ["GET","POST","PUT","DELETE"],
"restricted": true,
"auth_type": "apikey",
"cache": false,
"rate_limit": {
"enabled": true,
"requests_per_minute": 60,
"burst": 120
},
"errors": {
"expose_stack": false,
"default_locale": "en-US",
"codes": {
"VALIDATION_FAILED": 400,
"NOT_FOUND": 404,
"SERVER_ERROR": 500
}
},
"authentication": {
"type": "jwt",
"secret_env": "API_JWT_SECRET",
"token_ttl": 3600
},
"authorization": {
"restricted": true,
"roles": ["admin","user"],
"anonymous_read": false
}
}
}
Best Practices & Notes
- Start Closed – Ship with
"enabled": false
until your middleware pipeline underapi
is wired and tested. - One Auth Strategy – Keep
auth_type
in sync withauthentication.type
to avoid confusion. - Throttle Before Auth – Place rate-limit middleware before authentication to blunt brute‑force attacks.
- Health Check – Expose a
GET /ping
endpoint returning200 OK
for uptime monitors. - DNS & SSL – Automate certificate issuance for each
{domain_id}
subdomain (Let’s Encrypt, etc.).