HTTP Plugin Guide
Use this guide when working with cookies, sessions, response helpers, or HTTP plugin configuration in FaasJS APIs.
Overview
The HTTP plugin is built into @faasjs/core and every defineApi endpoint requires it after plugin resolution. The standard starters declare http in src/faas.yaml, and the config-driven loader treats that plugin id as the built-in Http class from @faasjs/core. Direct defineApi().export().handler() tests or one-off APIs must inject new Http() in code or provide api.config.plugins.http.
It only processes invocations when data.context.runtime is missing or set to api. When the same plugin is inherited by a background job, context.runtime === 'job' makes the HTTP plugin call await next() without parsing HTTP params, injecting HTTP helpers, or rewriting job params.
It injects the following fields into every defineApi handler:
cookie— read and write cookiessession— encrypted session storage backed by a signed cookieheaders— raw request headersbody— raw request bodysetHeader— set a response headersetContentType— set the response Content-TypesetStatusCode— set the HTTP status codesetBody— set the response body
Cookie
Reading cookies
import { defineApi } from '@faasjs/core'
export default defineApi({
async handler({ cookie }) {
const theme = cookie.read('theme')
return { theme }
},
})
Writing cookies
cookie.write('theme', 'dark')
Set null or undefined to expire a cookie:
cookie.write('theme', null)
Per-cookie attribute overrides:
cookie.write('token', 'abc', {
domain: '.example.com',
path: '/',
expires: 86400, // max-age seconds
secure: true,
httpOnly: true,
sameSite: 'Lax',
})
Default cookie attributes
| Attribute | Default |
|---|---|
path |
/ |
expires |
31536000 |
secure |
true |
httpOnly |
true |
Override these globally in faas.yaml (see Configuration).
Session
Session data is encrypted (AES-256-CBC) and signed (HMAC-SHA256), then stored in a cookie.
Reading session values
const userId = cookie.session.read('userId')
Writing session values
cookie.session.write('userId', 'u_123')
Set null or undefined to remove a key:
cookie.session.write('userId', null)
Persisting changes
Session writes are held in memory. The HTTP plugin calls session.update() automatically after each request, so you normally do not need to call it. Call it explicitly only when you need the cookie header before the response is built:
cookie.session.write('locale', 'zh-CN')
cookie.session.update()
Typical login/logout pattern
import { defineApi, HttpError } from '@faasjs/core'
export default defineApi({
async handler({ cookie, params }) {
// Login
const user = await authenticate(params)
cookie.session.write('userId', user.id)
return { ok: true }
},
})
export default defineApi({
async handler({ cookie }) {
// Logout
cookie.session.write('userId', null)
return { ok: true }
},
})
Reading current user in other APIs
import { defineApi, HttpError } from '@faasjs/core'
export default defineApi({
async handler({ cookie }) {
const userId = cookie.session.read('userId')
if (!userId) throw new HttpError({ statusCode: 401, message: 'Not authenticated' })
return { userId }
},
})
Response helpers
setHeader
setHeader('X-Custom', 'value')
Header names are lowercased automatically.
setContentType
Accepts a ContentType key or a raw MIME type:
setContentType('json')
setContentType('text/html', 'utf-8')
setContentType('application/pdf')
setStatusCode
setStatusCode(201)
setBody
setBody({ custom: 'payload' })
setBody('raw string')
ContentType enum
Use with setContentType for common MIME types:
| Key | Value |
|---|---|
plain |
text/plain |
html |
text/html |
xml |
application/xml |
csv |
text/csv |
css |
text/css |
javascript |
application/javascript |
json |
application/json |
jsonp |
application/javascript |
Configuration
Configure cookie and session defaults in src/faas.yaml under defaults.plugins.http.config.cookie:
defaults:
plugins:
http:
config:
cookie:
secure: false
domain: '.example.com'
sameSite: 'Lax'
session:
key: 'session_id'
secret: ${SESSION_SECRET}
salt: 'salt'
iterations: 100
Session configuration
| Option | Default | Description |
|---|---|---|
key |
'key' |
Cookie name for the session payload |
secret |
(required) | Secret used to derive encryption and signing keys |
salt |
'salt' |
Salt for encryption key derivation |
signedSalt |
'signedSalt' |
Salt for signing key derivation |
keylen |
64 |
Derived key length in bytes |
iterations |
100 |
PBKDF2 iteration count |
digest |
'sha256' |
Hash algorithm |
cipherName |
'aes-256-cbc' |
Encryption cipher |
Environment variable injection
Configuration values can also come from environment variables using the pattern SECRET_<NAME>_<KEY_PATH>:
SECRET_HTTP_COOKIE_SESSION_SECRET=my-secret
SECRET_HTTP_COOKIE_SESSION_SALT=custom-salt
This is resolved at plugin mount time and merged into the config object.
Security
- Always set
cookie.session.secretin production. Use an environment variable reference (${SECRET}) rather than a literal infaas.yaml. - Keep
cookie.secure: truein production so cookies are only sent over HTTPS. - Session data is encrypted and signed, but keep payloads small and avoid storing secrets that never need to leave the server.
- Do not log cookie or session content in production.
See Also
- HTTP Protocol Specification — normative specification for request/response transport behavior
- defineApi Guide — building API endpoints that receive these injected fields
Review Checklist
- Cookie and session operations happen inside the handler, not in module scope
- Session writes are followed by
session.update()only when the cookie header is needed before the response (otherwise automatic) - Login sets
session.write, logout setssession.writewithnull cookie.session.secretis configured in production via environment variablecookie.secureistruein production,falsein development- Sensitive data is not stored in cookies or sessions unnecessarily