Skip to content

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/…
  1. DNS – Create an A or CNAME record for each domain_id (e.g., api.example.com, sandbox.example.com) pointing at your app host.
  2. Middleware – Register your global API middleware under the api alias in configs/middleware.php.
  3. Enable – Flip "enabled" to true in api.json; the framework mounts all routes at boot.

To summarize:

  1. Choose a Subdomain: set "domain_id" (e.g., "api"api.example.com).
  2. DNS Records: point that domain to your server.
  3. 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 in configs/.

bash
cp configs/api.sample.json configs/api.json
  1. Location Place api.json in the configs/ directory of your project.

  2. Subdomain Setup Decide on a domain_id (e.g., "api") and create a matching subdomain (api.example.com). Ensure SSL/TLS certs cover it.

  3. Single Source of Truth All API settings—methods, auth, rate limits, error codes, etc.—live in this file. Edits take effect on next deploy.

  4. 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

InputDescriptionExample
enabledMaster on/off switch. false disables all API routes.false
domain_idSubdomain slug—becomes https://{domain_id}.example.com"api"
charsetDefault response encoding."utf-8"
methodsAllowed HTTP verbs (array).["GET","POST","PUT","DELETE"]
jsonc
"api": {
  "enabled": false,
  "domain_id": "api",
  "charset": "utf-8",
  "methods": ["GET","POST","PUT","DELETE"],
  ...
}

Access Control

InputDescriptionExample
restrictedWhen true, blocks unauthenticated requests by default.true
auth_typeShorthand guard: "apikey" or "jwt"."apikey"
jsonc
"restricted": true,
"auth_type": "apikey",

Tip: To switch to JWT, set both auth_type and authentication.type to "jwt" (and remove API‑key logic).


Caching

InputDescriptionExample
cachefalse = no caching, or an object when needed.false
jsonc
"cache": false,

Rate Limiting

InputDescriptionExample
rate_limit.enabledToggle throttling middleware.true
rate_limit.requests_per_minuteSteady-state cap per token/IP per minute.60
rate_limit.burstExtra allowance for short traffic spikes.120
jsonc
"rate_limit": {
  "enabled": true,
  "requests_per_minute": 60,
  "burst": 120
},

Error Handling

InputDescriptionExample
errors.expose_stackShow stack traces in JSON (never in production).false
errors.default_localeFallback locale for error messages."en-US"
errors.codesMap internal codes → HTTP status.{ "NOT_FOUND":404 }
jsonc
"errors": {
  "expose_stack": false,
  "default_locale": "en-US",
  "codes": {
    "VALIDATION_FAILED": 400,
    "NOT_FOUND": 404,
    "SERVER_ERROR": 500
  }
},

Authentication

InputDescriptionExample
authentication.typeDriver: "apikey" or "jwt"."jwt"
authentication.secret_envEnv var name for JWT secret."API_JWT_SECRET"
authentication.token_ttlJWT lifetime in seconds.3600
jsonc
"authentication": {
  "type": "jwt",
  "secret_env": "API_JWT_SECRET",
  "token_ttl": 3600
},

Authorization (RBAC)

InputDescriptionExample
authorization.restrictedWhen true, every route goes through an RBAC check.true
authorization.rolesArray of valid role slugs.["admin","user"]
authorization.anonymous_readAllow unauthenticated GETs if set to true.false
jsonc
"authorization": {
  "restricted": true,
  "roles": ["admin","user"],
  "anonymous_read": false
}

Example api.json

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 under api is wired and tested.
  • One Auth Strategy – Keep auth_type in sync with authentication.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 returning 200 OK for uptime monitors.
  • DNS & SSL – Automate certificate issuance for each {domain_id} subdomain (Let’s Encrypt, etc.).