Fortune HTTP
raw JSON →Fortune HTTP (`fortune-http`) provides the HTTP implementation for Fortune.js, a non-native graph database abstraction layer for Node.js and web browsers. Currently at version 1.2.28, this module is essential for exposing Fortune.js APIs over HTTP, including default serializers for JSON, HTML, form-encoded data, and form data. It acts as the networking layer, converting internal Fortune.js requests and responses into HTTP interactions. It is explicitly stated as being required for other HTTP serializers within the Fortune.js ecosystem. While a specific release cadence isn't defined, it typically evolves alongside the main Fortune.js project. Its key differentiator is its tight integration with Fortune.js, offering a structured, ad hoc JSON over HTTP API and an HTML interface, contrasting with other network protocols like WebSocket also supported by Fortune.js.
Common errors
error TypeError: fortuneHTTP is not a function ↓
const fortuneHTTP = require('fortune-http') as the primary method of importing. error UnhandledPromiseRejectionWarning: Unhandled promise rejection. ↓
.catch() block to the listener call, e.g., listener(request, response).catch(console.error). error Error: Headers already sent ↓
fortune-http listener is positioned as the last middleware in the chain for the routes it is intended to handle, as it typically ends the response by default. error Fortune HTTP Error: A Fortune instance is required. ↓
Fortune.js to fortuneHTTP, like fortuneHTTP(myFortuneInstance, options). error CSRF token mismatch ↓
CSRF_ in your form submissions as required by the fortune-http form serializers for CSRF protection. Warnings
gotcha The `fortuneHTTP` function returns a Promise. All calls to the listener must explicitly handle promise rejections (e.g., with `.catch()`) to prevent unhandled promise errors from crashing the Node.js process. ↓
gotcha When used with middleware frameworks like Express, the `fortune-http` listener should typically be the last middleware in the stack for a given route, as it ends the response by default. Placing other middleware after it may lead to 'Headers already sent' errors. ↓
gotcha Form serializers in `fortune-http` require all payloads to include cookie values prefixed with `CSRF_` for Cross-Site Request Forgery (CSRF) protection. Omitting these will result in failed form submissions. ↓
gotcha The special field `__method__` can be used within form payloads to override the HTTP method. This is a specific mechanism for scenarios where standard HTTP methods cannot be used directly. ↓
deprecated Previous versions of Fortune.js (before 5.0.0) had HTTP capabilities directly within the core `fortune.net.http` namespace. `fortune-http` was extracted as a separate module in Fortune.js v5.0.0. Older applications may need to update their import paths. ↓
Install
npm install fortune-http yarn add fortune-http pnpm add fortune-http Imports
- fortuneHTTP wrong
import fortuneHTTP from 'fortune-http'correctconst fortuneHTTP = require('fortune-http') - listener wrong
const listener = new fortuneHTTP(fortuneInstance, options)correctconst listener = fortuneHTTP(fortuneInstance, options) - requestHandler wrong
server.on('request', listener)correctserver.on('request', (request, response) => listener(request, response).catch(console.error))
Quickstart
const http = require('http');
const fortuneHTTP = require('fortune-http');
// A mock Fortune.js instance for demonstration purposes.
// In a real application, you would initialize Fortune.js.
const mockFortuneInstance = {
request: async (type, payload) => {
console.log(`Fortune.js request: ${type}`, payload);
// Simulate database operations
if (type === 'create') return { records: [{ id: Math.random().toString(36).substring(7), ...payload.records[0] }] };
if (type === 'find') return { records: [{ id: 'abc', message: 'Hello from Fortune!' }] };
return { records: [] };
}
};
// Pass in a Fortune instance and an optional options object.
const listener = fortuneHTTP(mockFortuneInstance, {
// Example customization for HTML serializer (default prefix is empty string)
prefix: '/api'
});
const server = http.createServer((request, response) =>
listener(request, response)
.catch(error => {
console.error('Fortune HTTP Error:', error.stack);
if (!response.headersSent) {
response.writeHead(500, { 'Content-Type': 'application/json' });
response.end(JSON.stringify({ error: error.message }));
}
})
);
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
console.log(`Fortune HTTP server listening on http://localhost:${PORT}`);
console.log(`Try: curl http://localhost:${PORT}/api/find/posts`);
console.log(`Try: curl -X POST -H "Content-Type: application/json" -d '{"records": [{"message": "New post!"}]}' http://localhost:${PORT}/api/create/posts`);
});