Skip to content

Commit 6ed9eeb

Browse files
committed
docs: add cloud mode documentation for v2.0.0
- Add Cloud Mode guide page with setup, circuit breaker and security sections - Update getting-started with cloud mode code examples - Update configuration reference: remove mode as required param, add cloudUrl/apiKey options - Update what-is-apiforge to mention cloud mode as optional - Update local dashboard page with cloud mode info banner - Add Cloud Mode to sidebar, bump version to v2.0.0
1 parent f3bf6a1 commit 6ed9eeb

7 files changed

Lines changed: 225 additions & 39 deletions

File tree

docs/.vitepress/config.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export default defineConfig({
2121
{ text: 'Features', link: '/features/insights' },
2222
{ text: 'API Reference', link: '/guide/configuration' },
2323
{
24-
text: 'v1.0.3',
24+
text: 'v2.0.0',
2525
items: [
2626
{ text: 'Changelog (Node.js)', link: 'https://github.com/APIForge-Organisation/sdk-nodejs/blob/main/CHANGELOG.md' },
2727
{ text: 'Changelog (Python)', link: 'https://github.com/APIForge-Organisation/sdk-python/blob/main/CHANGELOG.md' },
@@ -42,9 +42,10 @@ export default defineConfig({
4242
],
4343
},
4444
{
45-
text: 'Dashboard',
45+
text: 'Deployment',
4646
items: [
4747
{ text: 'Local Dashboard', link: '/guide/dashboard' },
48+
{ text: 'Cloud Mode', link: '/guide/cloud-mode' },
4849
],
4950
},
5051
],

docs/guide/cloud-mode.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# Cloud Mode
2+
3+
Cloud mode sends your metrics to the APIForge SaaS instead of storing them locally. The local SQLite database and the embedded dashboard are not started — everything is handled on the cloud side.
4+
5+
## When to use cloud mode
6+
7+
| | Local mode | Cloud mode |
8+
|---|---|---|
9+
| Setup | Zero config | Requires an API key |
10+
| Data storage | SQLite on your server | APIForge SaaS |
11+
| Dashboard | Embedded (port 4242) | Cloud dashboard |
12+
| Multi-service | One DB per machine | Unified across all services |
13+
| Internet required | No | Yes |
14+
15+
Use **local mode** during development or when you want full data ownership.
16+
Use **cloud mode** in production when you want a unified view across multiple services and deployments.
17+
18+
## Setup
19+
20+
### 1. Create a project
21+
22+
Sign in to the APIForge dashboard and create a project. You will receive an API key starting with `af_`.
23+
24+
::: warning
25+
The API key is shown only once at creation time. Store it immediately in your secrets manager or environment variables.
26+
:::
27+
28+
### 2. Add the middleware
29+
30+
::: code-group
31+
32+
```js [Node.js]
33+
const { apiforge } = require('apiforgejs')
34+
35+
app.use(apiforge({
36+
cloudUrl: 'https://api.apiforge.fr',
37+
apiKey: process.env.APIFORGE_API_KEY,
38+
service: 'my-api',
39+
env: process.env.NODE_ENV,
40+
release: process.env.npm_package_version,
41+
}))
42+
```
43+
44+
```python [Python]
45+
import os
46+
from apiforgepy import ApiForgeMiddleware
47+
48+
app.add_middleware(
49+
ApiForgeMiddleware,
50+
cloud_url=os.environ["APIFORGE_CLOUD_URL"],
51+
api_key=os.environ["APIFORGE_API_KEY"],
52+
service="my-api",
53+
env=os.environ.get("ENV", "production"),
54+
release=os.environ.get("RELEASE"),
55+
)
56+
```
57+
58+
:::
59+
60+
### 3. Set environment variables
61+
62+
```bash
63+
APIFORGE_CLOUD_URL=https://api.apiforge.fr
64+
APIFORGE_API_KEY=af_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
65+
```
66+
67+
## How it works
68+
69+
1. The SDK intercepts each request and records route, method, status code, and latency in memory.
70+
2. Every `flushInterval` milliseconds (default: 60s), the buffer is aggregated into per-route statistics and sent to `POST /ingest` on the SaaS API.
71+
3. The SaaS stores the metrics in TimescaleDB and makes them available through the cloud dashboard.
72+
73+
## Circuit breaker
74+
75+
If the SaaS API is unreachable, the SDK automatically backs off:
76+
77+
- After **5 consecutive failures**, the transport pauses for **60 seconds**.
78+
- During the pause, flush calls are silently skipped — your application is never blocked.
79+
- After the pause, the SDK resumes sending normally.
80+
81+
A warning is printed to stdout when the circuit opens:
82+
83+
```
84+
[apiforgejs] Cloud flush failures — pausing for 60s. Error: ...
85+
[apiforgepy] Cloud flush failures — pausing for 60s. Error: ...
86+
```
87+
88+
## Rotating an API key
89+
90+
If your API key is compromised, rotate it from the dashboard (`Project settings → Rotate key`). The old key is invalidated immediately. Update the environment variable and redeploy.
91+
92+
## Security
93+
94+
- API keys are stored as HMAC-SHA256 hashes server-side — the raw key is never persisted.
95+
- All traffic between the SDK and the SaaS is encrypted over HTTPS.
96+
- The SDK never reads request bodies, headers, cookies, or query parameter values regardless of mode.

docs/guide/configuration.md

Lines changed: 60 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,28 @@
22

33
## Node.js
44

5-
All options are passed to the `apiforge()` factory. Every option is optional except `mode`.
5+
All options are passed to the `apiforge()` factory. All options are optional — calling `apiforge()` with no arguments starts local mode with defaults.
66

77
```js
8+
// Local mode (default)
89
app.use(apiforge({
9-
mode: 'local',
1010
dbPath: '.apiforge.db',
1111
dashboardPort: 4242,
1212
flushInterval: 60_000,
1313
env: 'production',
14-
release: 'v1.4.0',
14+
release: 'v2.0.0',
15+
service: 'user-service',
16+
sampling: 1.0,
17+
ignorePaths: ['/favicon.ico', '/health'],
18+
}))
19+
20+
// Cloud mode
21+
app.use(apiforge({
22+
cloudUrl: 'https://api.apiforge.fr',
23+
apiKey: process.env.APIFORGE_API_KEY,
24+
flushInterval: 60_000,
25+
env: 'production',
26+
release: 'v2.0.0',
1527
service: 'user-service',
1628
sampling: 1.0,
1729
ignorePaths: ['/favicon.ico', '/health'],
@@ -20,21 +32,32 @@ app.use(apiforge({
2032

2133
## Python
2234

23-
All options are passed to `ApiForgeMiddleware`. Every option is optional except `mode`.
35+
All options are passed to `ApiForgeMiddleware`. All options are optional.
2436

2537
```python
38+
# Local mode (default)
2639
app.add_middleware(
2740
ApiForgeMiddleware,
28-
mode="local",
2941
db_path=".apiforge.db",
3042
dashboard_port=4242,
3143
flush_interval=60_000, # ms
3244
env="production",
33-
release="v1.4.0",
45+
release="v2.0.0",
3446
service="user-service",
3547
sampling=1.0,
3648
ignore_paths=["/favicon.ico", "/health"],
3749
)
50+
51+
# Cloud mode
52+
app.add_middleware(
53+
ApiForgeMiddleware,
54+
cloud_url="https://api.apiforge.fr",
55+
api_key=os.environ["APIFORGE_API_KEY"],
56+
flush_interval=60_000,
57+
env="production",
58+
release="v2.0.0",
59+
service="user-service",
60+
)
3861
```
3962

4063
::: tip Python naming
@@ -45,12 +68,25 @@ Python uses `snake_case` for option names. All other semantics — including uni
4568

4669
## Options
4770

48-
### `mode` / `mode`
71+
### `cloudUrl` / `cloud_url`
72+
73+
- **Type:** `string | null`
74+
- **Default:** `null`
75+
76+
Base URL of the APIForge SaaS API. Required for cloud mode, along with `apiKey`. When set, local SQLite storage and the embedded dashboard are disabled.
77+
78+
---
79+
80+
### `apiKey` / `api_key`
81+
82+
- **Type:** `string | null`
83+
- **Default:** `null`
4984

50-
- **Type:** `'local'`
51-
- **Required:** yes
85+
Project API key, starting with `af_`. Generated from the APIForge dashboard when you create a project. Must be provided together with `cloudUrl`.
5286

53-
The storage and transport mode. Only `'local'` (SQLite) is available. SaaS mode is planned for a future version.
87+
::: warning Keep your API key secret
88+
Never commit your API key to source control. Use an environment variable: `process.env.APIFORGE_API_KEY` (Node.js) or `os.environ["APIFORGE_API_KEY"]` (Python).
89+
:::
5490

5591
---
5692

@@ -59,7 +95,7 @@ The storage and transport mode. Only `'local'` (SQLite) is available. SaaS mode
5995
- **Type:** `string`
6096
- **Default:** `'.apiforge.db'`
6197

62-
Path to the SQLite database file. Created automatically if it does not exist.
98+
Path to the SQLite database file (local mode only). Created automatically if it does not exist.
6399

64100
---
65101

@@ -68,18 +104,18 @@ Path to the SQLite database file. Created automatically if it does not exist.
68104
- **Type:** `number` / `int`
69105
- **Default:** `4242`
70106

71-
Port for the local dashboard HTTP server. Set to `0` to disable the dashboard entirely.
107+
Port for the local dashboard HTTP server (local mode only). Set to `0` to disable the dashboard entirely.
72108

73109
```js
74110
// Node.js
75-
apiforge({ mode: 'local', dashboardPort: 0 }) // no dashboard
76-
apiforge({ mode: 'local', dashboardPort: 9000 }) // custom port
111+
apiforge({ dashboardPort: 0 }) // no dashboard
112+
apiforge({ dashboardPort: 9000 }) // custom port
77113
```
78114

79115
```python
80116
# Python
81-
ApiForgeMiddleware(mode="local", dashboard_port=0) # no dashboard
82-
ApiForgeMiddleware(mode="local", dashboard_port=9000) # custom port
117+
ApiForgeMiddleware(dashboard_port=0) # no dashboard
118+
ApiForgeMiddleware(dashboard_port=9000) # custom port
83119
```
84120

85121
---
@@ -88,7 +124,7 @@ ApiForgeMiddleware(mode="local", dashboard_port=9000) # custom port
88124

89125
- **Type:** `number` / `int` (milliseconds) — Default: `60000`
90126

91-
How often the in-memory buffer is flushed to SQLite. Both SDKs use **milliseconds**.
127+
How often the in-memory buffer is flushed (to SQLite in local mode, to the SaaS API in cloud mode).
92128

93129
::: warning Minimum recommended value
94130
Values below 5 seconds may impact performance under high traffic. The default of 60s is appropriate for most applications.
@@ -100,9 +136,9 @@ Values below 5 seconds may impact performance under high traffic. The default of
100136

101137
- **Type:** `string`
102138
- **Default (Node.js):** `process.env.NODE_ENV ?? 'production'`
103-
- **Default (Python):** `'production'`
139+
- **Default (Python):** `os.environ.get("ENV", "production")`
104140

105-
Environment label stored with each metric.
141+
Environment label stored with each metric (e.g. `'production'`, `'staging'`).
106142

107143
---
108144

@@ -115,13 +151,12 @@ Version tag for the current deployment. When provided, APIForge creates a compar
115151

116152
```js
117153
// Node.js
118-
apiforge({ mode: 'local', release: process.env.npm_package_version })
154+
apiforge({ release: process.env.npm_package_version })
119155
```
120156

121157
```python
122158
# Python
123-
import os
124-
ApiForgeMiddleware(mode="local", release=os.environ.get("RELEASE"))
159+
ApiForgeMiddleware(release=os.environ.get("RELEASE"))
125160
```
126161

127162
See [Release Tracking](/features/release-tracking) for details.
@@ -133,7 +168,7 @@ See [Release Tracking](/features/release-tracking) for details.
133168
- **Type:** `string`
134169
- **Default:** `'default'`
135170

136-
Service name, used to distinguish multiple APIs sharing the same database.
171+
Service name. In local mode, used to distinguish multiple APIs sharing the same database. In cloud mode, used to group routes in the dashboard.
137172

138173
---
139174

@@ -160,7 +195,7 @@ Paths to exclude from instrumentation. Supports exact matches.
160195
### Node.js
161196

162197
```js
163-
const mw = apiforge({ mode: 'local' })
198+
const mw = apiforge()
164199
app.use(mw)
165200

166201
process.on('SIGTERM', () => {
@@ -174,8 +209,7 @@ process.on('SIGTERM', () => {
174209
```python
175210
import atexit
176211

177-
mw = ApiForgeMiddleware(mode="local")
178-
app.add_middleware(mw)
212+
mw = ApiForgeMiddleware(app)
179213

180214
atexit.register(mw.shutdown)
181215
```

docs/guide/dashboard.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
The local dashboard is a built-in web UI served automatically by the SDK on port 4242 (configurable). It is identical across all SDKs — the same interface whether you run Node.js or Python.
44

5+
::: info Cloud mode
6+
In cloud mode, the local dashboard is not started. Metrics are visualized in the APIForge cloud dashboard instead. See [Cloud Mode](/guide/cloud-mode).
7+
:::
8+
59
```
610
http://localhost:4242
711
```
@@ -53,11 +57,11 @@ See [Automatic Insights](/features/insights).
5357
::: code-group
5458

5559
```js [Node.js]
56-
app.use(apiforge({ mode: 'local', dashboardPort: 0 }))
60+
app.use(apiforge({ dashboardPort: 0 }))
5761
```
5862

5963
```python [Python]
60-
app.add_middleware(ApiForgeMiddleware, mode="local", dashboard_port=0)
64+
app.add_middleware(ApiForgeMiddleware, dashboard_port=0)
6165
```
6266

6367
:::
@@ -72,7 +76,7 @@ app.use(apiforge({ mode: 'local', dashboardPort: 9090 }))
7276
```
7377

7478
```python [Python]
75-
app.add_middleware(ApiForgeMiddleware, mode="local", dashboard_port=9090)
79+
app.add_middleware(ApiForgeMiddleware, dashboard_port=9090)
7680
# Dashboard → http://localhost:9090
7781
```
7882

0 commit comments

Comments
 (0)