### Minimal Fastify Express Setup Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/examples.md This is the most basic setup for using @fastify/express. It registers the plugin and defines a simple root route. ```javascript const Fastify = require('fastify') const expressPlugin = require('@fastify/express') const fastify = Fastify() await fastify.register(expressPlugin) fastify.get('/', async () => { return { hello: 'world' } }) await fastify.listen({ port: 3000 }) ``` -------------------------------- ### Install @fastify/express Plugin Source: https://github.com/fastify/fastify-express/blob/main/README.md Install the @fastify/express plugin using npm. This is the first step to integrating Express compatibility into your Fastify application. ```bash npm i @fastify/express ``` -------------------------------- ### Serving Static Files with Fastify Express Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/examples.md This example demonstrates how to serve static files from a directory using the 'serve-static' middleware, aliased via @fastify/express. ```javascript const Fastify = require('fastify') const expressPlugin = require('@fastify/express') const serveStatic = require('serve-static') const path = require('path') const fastify = Fastify() await fastify.register(expressPlugin) // Serve static files from public directory under /static path fastify.use('/static', serveStatic(path.join(__dirname, 'public'))) fastify.get('/', async () => { return { message: 'Static files served at /static' } }) await fastify.listen({ port: 3000 }) ``` -------------------------------- ### URL Decoding Example Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/url-normalization.md Demonstrates how raw encoded characters in the URL are decoded. The original URL is preserved in `req.originalUrl`. ```text Input: /%61dmin?test=%76alue Output: /admin?test=value ``` -------------------------------- ### Fix POST request hangs by replacing body-parser Source: https://github.com/fastify/fastify-express/blob/main/README.md This example shows the corrected setup to resolve POST request hangs by removing `body-parser`, installing `@fastify/formbody`, and configuring `@fastify/express` to run after the formbody logic. ```javascript const Fastify = require('fastify') const Express = require('express') const expressPlugin = require('@fastify/express') const fastifyFormBody = require('@fastify/formbody') const fastify = Fastify() const express = Express() await fastify.register(fastifyFormBody) await fastify.register(expressPlugin, { // run express after `@fastify/formbody` logic expressHook: 'preHandler' }) fastify.use(express) // it works! fastify.post('/hello', (req, reply) => { return { hello: 'world' } }) ``` -------------------------------- ### Using Helmet Security Headers with Fastify Express Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/examples.md This example demonstrates how to add security headers to your Fastify application using the 'helmet' middleware via @fastify/express. ```javascript const Fastify = require('fastify') const expressPlugin = require('@fastify/express') const helmet = require('helmet') const fastify = Fastify() await fastify.register(expressPlugin) fastify.use(helmet()) fastify.get('/', async () => { return { secure: true } }) await fastify.listen({ port: 3000 }) ``` -------------------------------- ### useSemicolonDelimiter Precedence Example Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/url-normalization.md Demonstrates the precedence when both '?' and ';' are present and useSemicolonDelimiter is true. The first delimiter encountered determines the split. ```javascript /path;first?second // useSemicolonDelimiter: true // → path: /path, query: ?first?second /path?first;second // useSemicolonDelimiter: true // → path: /path, query: ?first;second ``` -------------------------------- ### Normalized Request URL Example Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/url-normalization.md Demonstrates the normalized req.url property. The client-sent URL is decoded and formatted according to the default configuration. ```javascript // Client sends: /%61dmin?test=%76alue // With default config: /admin?test=value req.url === '/admin?test=value' // true ``` -------------------------------- ### Testing URL Normalization with Explicit Configuration Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/url-normalization.md Verify URL normalization behavior by setting up test cases with specific inputs and expected outputs. This example demonstrates how to configure Fastify and Express to test these scenarios. ```javascript const Fastify = require('fastify') const expressPlugin = require('@fastify/express') const testCases = [ { input: '//', expected: '/' }, { input: '//api', expected: '/api' }, { input: '/api//v1', expected: '/api/v1' }, { input: '/%61pi', expected: '/api' }, { input: '/path?q=1', expected: '/path?q=1' }, ] async function test() { const fastify = Fastify({ routerOptions: { ignoreDuplicateSlashes: true } }) await fastify.register(expressPlugin) fastify.use((req, res, next) => { // Verify normalization const testCase = testCases.find(t => t.input === req.originalUrl) if (testCase && req.url === testCase.expected) { console.log(`✓ ${testCase.input} → ${req.url}`) } else { console.log(`✗ ${req.originalUrl} → ${req.url} (unexpected)`) } res.end() }) await fastify.listen({ port: 3000 }) } ``` -------------------------------- ### Example Usage of @fastify/express Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/types.md Demonstrates how to register the @fastify/express plugin with Fastify and subsequently use Express middleware and access the Express application instance. Ensure the plugin is registered before attempting to use its added properties. ```typescript import Fastify from 'fastify' import fastifyExpress from '@fastify/express' const fastify = Fastify() await fastify.register(fastifyExpress) // Now TypeScript recognizes these properties fastify.use((req, res, next) => { // middleware code next() }) fastify.express.disable('x-powered-by') ``` -------------------------------- ### Troubleshooting POST request hangs with body-parser Source: https://github.com/fastify/fastify-express/blob/main/README.md This example demonstrates a common issue where POST requests with bodies hang when using `body-parser` with `fastify-express`. It shows the problematic setup. ```javascript const Fastify = require('fastify') const Express = require('express') const expressPlugin = require('@fastify/express') const bodyParser = require('body-parser') const fastify = Fastify() const express = Express() express.use(bodyParser.urlencoded({ extended: false })) await fastify.register(expressPlugin) fastify.use(express) // this route will never reply fastify.post('/hello', (req, reply) => { return { hello: 'world' } }) ``` -------------------------------- ### Registering Express Middleware with Fastify Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/api-reference.md Register Express middleware with Fastify. This example shows how to register middleware globally, for specific paths, and for multiple paths. It also demonstrates chaining multiple registrations and using custom middleware functions. ```javascript const fastify = Fastify() const express = require('express') const cors = require('cors') await fastify.register(expressPlugin) // Register middleware for all paths fastify.use(cors()) // Register middleware for specific path fastify.use('/api', cors()) // Register middleware for multiple paths fastify.use(['/api', '/admin'], (req, res, next) => { res.setHeader('x-custom', 'value') next() }) // Chain multiple registrations fastify.use(cors()) .use('/public', express.static('./public')) .use(require('helmet')()) // Custom middleware function fastify.use((req, res, next) => { console.log(req.url) next() }) ``` -------------------------------- ### Fastify and Express Type Declarations Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/types.md Shows example declarations for FastifyInstance and FastifyRequest, which are re-exported from the 'fastify' package. These types are fundamental for working with Fastify server instances and requests. ```typescript import { FastifyInstance, FastifyRequest } from 'fastify' declare const fastify: FastifyInstance declare const request: FastifyRequest ``` -------------------------------- ### Common ProxyHandler Usage Example Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/types.md Demonstrates how to create a ProxyHandler to intercept property access and assignment. Use this pattern to expose Fastify-specific properties or customize how properties are set on the wrapped Express request object. ```javascript createProxyHandler: (fastifyReq) => ({ get(target, prop) { // Return Fastify properties via Express request if (prop === 'userId') return fastifyReq.user?.id return target[prop] }, set(target, prop, value) { // Customize property assignment if (prop === 'data') { fastifyReq.customData = value return true } return Reflect.set(target, prop, value) } }) ``` -------------------------------- ### Configure Router Options for URL Normalization Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/configuration.md Pass router options to the Fastify constructor to control URL normalization for Express middleware. This example enables ignoring duplicate slashes and using semicolons as query delimiters. ```javascript const fastify = Fastify({ routerOptions: { ignoreDuplicateSlashes: true, useSemicolonDelimiter: true } }) await fastify.register(expressPlugin) fastify.use((req, res, next) => { // req.raw.url has been normalized according to these options console.log(req.raw.url) }) ``` -------------------------------- ### Using CORS Middleware with Fastify Express Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/examples.md This example shows how to enable Cross-Origin Resource Sharing (CORS) by using the 'cors' middleware with @fastify/express. ```javascript const Fastify = require('fastify') const expressPlugin = require('@fastify/express') const cors = require('cors') const fastify = Fastify() await fastify.register(expressPlugin) fastify.use(cors()) fastify.get('/', async () => { return { message: 'CORS enabled' } }) await fastify.listen({ port: 3000 }) ``` -------------------------------- ### splitPathAndQuery with Semicolon Delimiter Enabled Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/url-normalization.md Example of the internal splitPathAndQuery function when useSemicolonDelimiter is set to true. It recognizes both '?' and ';' as query string delimiters. ```javascript // useSemicolonDelimiter: true splitPathAndQuery('/api/users;id=1', true) // → { path: '/api/users', query: '?id=1' } ``` -------------------------------- ### Body Parsing with Fastify Express Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/examples.md This example shows how to configure JSON and URL-encoded body parsing using Express's built-in middleware with @fastify/express. ```javascript const Fastify = require('fastify') const expressPlugin = require('@fastify/express') const express = require('express') const fastify = Fastify() await fastify.register(expressPlugin) // Parse JSON and form-encoded bodies fastify.use(express.json()) fastify.use(express.urlencoded({ extended: false })) fastify.post('/api/data', async (request) => { return { received: request.body } }) await fastify.listen({ port: 3000 }) ``` -------------------------------- ### Examples of removeDuplicateSlashes Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/url-normalization.md Demonstrates the behavior of `removeDuplicateSlashes` with various inputs containing multiple slashes. ```javascript removeDuplicateSlashes('/api/users') // '/api/users' removeDuplicateSlashes('//api/users') // '/api/users' removeDuplicateSlashes('/api//users') // '/api/users' removeDuplicateSlashes('///api///users') // '/api/users' removeDuplicateSlashes('/') // '/' removeDuplicateSlashes('//') // '/' ``` -------------------------------- ### splitPathAndQuery with Semicolon Delimiter Disabled Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/url-normalization.md Example of the internal splitPathAndQuery function when useSemicolonDelimiter is set to false. It uses '?' as the query string delimiter. ```javascript // useSemicolonDelimiter: false splitPathAndQuery('/api/users?id=1', false) // → { path: '/api/users', query: '?id=1' } ``` -------------------------------- ### Original vs. Normalized Request URL Example Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/url-normalization.md Compares the original request URL (req.originalUrl) with the normalized URL (req.url). The original URL retains the client's exact input, including encoding. ```javascript // Client sends: /%61dmin?test=%76alue req.originalUrl === '/%61dmin?test=%76alue' // true req.url === '/admin?test=value' // true ``` -------------------------------- ### useSemicolonDelimiter: false Example Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/url-normalization.md With useSemicolonDelimiter set to false, only the question mark (?) is recognized as a query string delimiter. Semicolons are treated as part of the URL path. ```javascript const fastify = Fastify({ routerOptions: { useSemicolonDelimiter: false } }) // Only ? is a query delimiter // /path?query=value → path: /path, query: ?query=value // /path;param=value → path: /path;param=value, query: (none) ``` -------------------------------- ### Optimized Fastify Express Proxy Handler Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/configuration.md Implement an optimized proxy handler for the Fastify Express plugin by performing quick property checks. Avoid expensive operations like database calls within the 'get' trap to maintain performance. ```javascript // Good: quick property checks createProxyHandler: (fastifyReq) => ({ get(target, prop) { // Fast string comparison if (prop === 'userId') return fastifyReq.user?.id return target[prop] } }) ``` ```javascript // Avoid: expensive operations createProxyHandler: (fastifyReq) => ({ get(target, prop) { // Bad: database calls in property access if (prop === 'user') return await db.getUser(fastifyReq.id) return target[prop] } }) ``` -------------------------------- ### Express Application Initialization and Configuration Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/module-structure.md Initializes a new Express application instance for the Fastify instance and disables the 'x-powered-by' header. ```javascript fastify.decorate('express', Express()) fastify.express.disable('x-powered-by') ``` -------------------------------- ### Accessing Cookies with Cookie Parser Middleware Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/request-response-enhancement.md To access parsed cookies via `req.cookies`, you must register a cookie parsing middleware like `cookie-parser` before your request handler. This example demonstrates the setup. ```javascript // With cookie-parser middleware fastify.use(require('cookie-parser')()) fastify.use((req, res, next) => { req.cookies // { sessionId: 'abc123' } next() }) ``` -------------------------------- ### Conditional Property Access in Express Middleware Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/configuration.md Utilize the `has` and `get` traps in createProxyHandler for conditional property checks and access within Express middleware. This example shows how to implement an `isAuthenticated` property based on the Fastify user's presence. ```javascript await fastify.register(expressPlugin, { createProxyHandler: (fastifyReq) => ({ has(target, prop) { // Custom property existence check if (prop === 'isAuthenticated') { return fastifyReq.user != null } return prop in target }, get(target, prop) { if (prop === 'isAuthenticated') { return fastifyReq.user != null } return target[prop] } }) }) fastify.use((req, res, next) => { if ('isAuthenticated' in req) { // Custom logic } next() }) ``` -------------------------------- ### ignoreDuplicateSlashes: false Example Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/url-normalization.md When ignoreDuplicateSlashes is false, consecutive slashes in URLs are preserved as-is. This is the default behavior. ```javascript const fastify = Fastify({ routerOptions: { ignoreDuplicateSlashes: false } }) // Request URLs are normalized as-is // /users → /users // //users → //users // /users// → /users// ``` -------------------------------- ### Instance Methods: fastify.use() Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/README.md The `fastify.use()` method allows you to register Express middleware. It can be used to apply middleware globally to all paths, to a specific path, or to multiple specified paths. ```APIDOC ## Instance Methods: `fastify.use()` ### Description Registers Express middleware with the Fastify instance. This method allows for flexible application of middleware across different routing scopes. ### Method `fastify.use(path?, middleware)` ### Parameters - **path** (`string` | `string[]`): Optional. The path or an array of paths where the middleware should be applied. If omitted, the middleware is registered for all paths. - **middleware** (`function`): The Express-compatible middleware function. ### Returns - `fastify`: Returns the Fastify instance for chaining. ### Usage Examples 1. **Register for all paths:** ```javascript fastify.use(middleware) ``` 2. **Register for a specific path:** ```javascript fastify.use('/path', middleware) ``` 3. **Register for multiple paths:** ```javascript fastify.use(['/a', '/b'], middleware) ``` ``` -------------------------------- ### Instance Method: fastify.use() Signature Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/module-structure.md The `use` method is attached to the Fastify instance as `fastify.use`. It accepts an optional path and a function, normalizes the path, stores the middleware, and delegates to the Express app's `use()` method. It returns `this` for chainability. ```javascript function use(path, fn) ``` -------------------------------- ### Initialization of Internal Middleware Registry Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/module-structure.md Shows how the internal middleware registry is initialized as an empty array for a new Fastify instance. ```javascript fastify[kMiddlewares] = [] ``` -------------------------------- ### useSemicolonDelimiter: true Example Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/url-normalization.md When useSemicolonDelimiter is true, both question marks (?) and semicolons (;) are recognized as query string delimiters. This supports legacy URL formats. ```javascript const fastify = Fastify({ routerOptions: { useSemicolonDelimiter: true } }) // Both ? and ; are query delimiters // /path?query=value → path: /path, query: ?query=value // /path;param=value → path: /path, query: ?param=value // /path?query=value;extra → path: /path, query: ?query=value;extra ``` -------------------------------- ### Using Fastify Hooks and Express Middleware in Order Source: https://github.com/fastify/fastify-express/blob/main/README.md Demonstrates the order of execution for Fastify hooks and Express middleware. Middleware registered with 'fastify.use' runs during the 'onRequest' hook phase. ```js const fastify = require('fastify')() fastify .register(require('@fastify/express')) .register(subsystem) async function subsystem (fastify, opts) { fastify.addHook('onRequest', async (req, reply) => { console.log('first') }) fastify.use((req, res, next) => { console.log('second') next() }) fastify.addHook('onRequest', async (req, reply) => { console.log('third') }) } ``` -------------------------------- ### Query String Separation (Default) Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/url-normalization.md Shows how the path and query string are separated when `useSemicolonDelimiter` is false (default). ```text Input: /path?query=value Path: /path Query: ?query=value ``` -------------------------------- ### ignoreDuplicateSlashes: true Example Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/url-normalization.md When ignoreDuplicateSlashes is true, all consecutive slashes in URLs are collapsed into a single slash. This can help normalize URLs with potential formatting issues. ```javascript const fastify = Fastify({ routerOptions: { ignoreDuplicateSlashes: true } }) // All consecutive slashes become single slashes // /users → /users // //users → /users // /users// → /users // //api//v1//users → /api/v1/users ``` -------------------------------- ### Usage of Middleware Registry in onRegister Hook Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/module-structure.md Demonstrates how to copy the middleware list from a parent instance to a child instance during the onRegister hook to preserve middleware. ```javascript const middlewares = instance[kMiddlewares].slice() instance[kMiddlewares] = middlewares.slice() ``` -------------------------------- ### Apply Middleware to Multiple Paths Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/examples.md Apply Express middleware to multiple routes simultaneously by providing an array of paths to `fastify.use()`. ```javascript const Fastify = require('fastify') const expressPlugin = require('@fastify/express') const fastify = Fastify() await fastify.register(expressPlugin) // Custom header for multiple paths fastify.use(['/api', '/admin'], (req, res, next) => { res.setHeader('x-internal-api', 'true') next() }) fastify.get('/api/data', async () => { return { data: 'api' } }) fastify.get('/admin/users', async () => { return { users: [] } }) await fastify.listen({ port: 3000 }) ``` -------------------------------- ### Custom Hook with Express Middleware Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/examples.md Register Express middleware in a custom hook like 'preHandler' to process requests before route handlers. This example uses express.json() for body parsing. ```javascript const Fastify = require('fastify') const expressPlugin = require('@fastify/express') const express = require('express') const fastify = Fastify() // Register middleware in preHandler hook await fastify.register(expressPlugin, { expressHook: 'preHandler' }) // This allows body to be parsed before middleware fastify.use(express.json()) fastify.use((req, res, next) => { console.log('Body:', req.body) next() }) fastify.post('/data', async (request) => { return { received: request.body } }) await fastify.listen({ port: 3000 }) ``` -------------------------------- ### Access and Configure Express Instance Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/api-reference.md Access the underlying Express application instance to configure Express-specific settings or register middleware. Use this to disable headers or access the Express router. ```javascript const fastify = Fastify() await fastify.register(expressPlugin) // Disable the x-powered-by header fastify.express.disable('x-powered-by') // Check if a setting is disabled const isPoweredByDisabled = fastify.express.disabled('x-powered-by') // true // Access Express router const router = fastify.express._router // Register Express routes directly (not recommended for new code) fastify.express.get('/legacy', (req, res) => { res.json({ legacy: true }) }) ``` -------------------------------- ### Testing Express Application Endpoints with Curl Source: https://github.com/fastify/fastify-express/blob/main/README.md Verify the functionality of your integrated Express application endpoints using curl commands. Test GET, PATCH, and error handling scenarios. ```bash me@computer ~ % curl -X GET http://localhost:3000/hello {"hello":"world"}% me@computer ~ % curl -X GET http://localhost:3000/foo {"foo":"bar"}% me@computer ~ % curl -X GET http://localhost:3000/bar {"msg":"not found"}% me@computer ~ % curl -X PATCH -H 'content-type:application/json' http://localhost:3000/bar {"msg":"no req.body"}% me@computer ~ % curl -X PATCH -H 'content-type:application/json' -d '{"foo2":"bar2"}' http://localhost:3000/bar {"foo2":"bar2"}% ``` -------------------------------- ### TypeScript Usage with Options Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/module-structure.md Import and register the plugin in TypeScript, specifying options like expressHook and a custom createProxyHandler. ```typescript import fastifyExpress from '@fastify/express' import type { FastifyExpressOptions } from '@fastify/express' // Use with type await fastify.register(fastifyExpress, { expressHook: 'onRequest', createProxyHandler: (req) => ({ get(target, prop) { return target[prop] } }) }) ``` -------------------------------- ### Checking if Response Headers Have Been Sent Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/request-response-enhancement.md The `reply.raw.headersSent` property indicates whether response headers have already been sent. It's useful for preventing double-send errors. This example shows its usage before and after sending a response. ```javascript Object.defineProperty(reply.raw, 'headersSent', { get() { return replySent // Tracked by plugin }, configurable: true }) ``` ```javascript fastify.use((req, res, next) => { console.log(res.headersSent) // false initially next() }) fastify.use((req, res, next) => { res.send({ data: 'value' }) console.log(res.headersSent) // true after send }) ``` -------------------------------- ### Accessing Request Body with Express Middleware Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/request-response-enhancement.md To access `req.body` when using Express middleware with Fastify, ensure a body parser is used either by Fastify itself or an Express middleware. This example shows how to integrate `express.json()`. ```javascript // After Fastify body parser req.body // { name: 'value' } // Or Express body parser fastify.use(express.json()) // Then req.body available in subsequent middleware // Or with expressHook: 'preHandler' await fastify.register(expressPlugin, { expressHook: 'preHandler' }) ``` -------------------------------- ### Register Express Middleware with Fastify Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/README.md Use the `fastify.use()` method to register Express middleware. It can be applied to all paths, a specific path, or an array of paths. This method returns the Fastify instance for chaining. ```javascript fastify.use(middleware) // Register for all paths ``` ```javascript fastify.use('/path', middleware) // Register for specific path ``` ```javascript fastify.use(['/a', '/b'], middleware) // Register for multiple paths ``` ```javascript // Returns fastify for chaining ``` -------------------------------- ### splitPathAndQuery with No Query String Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/url-normalization.md Demonstrates the behavior of splitPathAndQuery when the URL does not contain a query string. ```javascript // No query splitPathAndQuery('/api/users', false) // → { path: '/api/users', query: '' } ``` -------------------------------- ### Handling Empty Path Request Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/url-normalization.md Illustrates how an empty path request (root) is normalized, collapsing multiple slashes to a single root slash. ```javascript // Request to root req.url === '/' // After normalization with ignoreDuplicateSlashes: true // //// → / ``` -------------------------------- ### Correct Middleware Registration Order Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/README.md Ensure middleware dependencies are registered in the correct sequence, with parsers preceding consumers, to guarantee proper execution. ```javascript // Correct: parser before consumer fastify.use(express.json()) fastify.use((req, res, next) => { console.log(req.body) // Available }) ``` ```javascript // Incorrect: consumer before parser fastify.use((req, res, next) => { console.log(req.body) // Undefined }) fastify.use(express.json()) ``` -------------------------------- ### Multi-Plugin Architecture with Express Middleware Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/examples.md Organize your application using multiple plugins, integrating Express middleware like Helmet and CORS at different levels. ```javascript const Fastify = require('fastify') const expressPlugin = require('@fastify/express') const cors = require('cors') const helmet = require('helmet') const fastify = Fastify() fastify .register(expressPlugin) .register(securityPlugin) .register(apiPlugin) async function securityPlugin(fastify, opts) { fastify.use(helmet()) } async function apiPlugin(fastify, opts) { fastify.use('/api', cors()) fastify.get('/api/users', async () => { return { users: [] } }) fastify.get('/api/posts', async () => { return { posts: [] } }) } await fastify.listen({ port: 3000 }) ``` -------------------------------- ### Router Configuration with Express Middleware Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/examples.md Configure Fastify's router options, such as ignoring duplicate slashes, and use Express middleware to log normalized URLs. ```javascript const Fastify = require('fastify') const expressPlugin = require('@fastify/express') const fastify = Fastify({ routerOptions: { ignoreDuplicateSlashes: true } }) await fastify.register(expressPlugin) fastify.use((req, res, next) => { console.log(`URL: ${req.url}`) // Normalized next() }) fastify.get('/api/users', async () => { return { users: [] } }) await fastify.listen({ port: 3000 }) // Both /api/users and //api//users map to the same route ``` -------------------------------- ### Client IP Address Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/request-response-enhancement.md Get the client's IP address. This respects the `trustProxy` setting. If `trustProxy` is false, it's the direct connection IP. If true, it's the first IP from the X-Forwarded-For header. ```javascript // Direct connection from 192.168.1.100 req.ip // '192.168.1.100' // Through proxy with X-Forwarded-For: 203.0.113.1, 198.51.100.2 // When trustProxy: true req.ip // '203.0.113.1' (first in chain) ``` -------------------------------- ### splitPathAndQuery with Multiple Delimiters Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/url-normalization.md Shows how splitPathAndQuery handles URLs with multiple potential query string delimiters when useSemicolonDelimiter is true. The first delimiter encountered determines the split. ```javascript // Multiple delimiters with useSemicolonDelimiter: true splitPathAndQuery('/path?first;second', true) // → { path: '/path', query: '?first;second' } ``` -------------------------------- ### Access Environment Variables in Express Middleware Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/configuration.md Register Express middleware that can access environment variables, typically loaded using a library like dotenv. This example demonstrates loading dotenv and accessing an API_KEY from process.env. ```javascript require('dotenv').config() const fastify = Fastify() await fastify.register(expressPlugin) // Express middleware can access process.env fastify.use((req, res, next) => { const apiKey = process.env.API_KEY next() }) ``` -------------------------------- ### Simple API Key Middleware Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/examples.md Implement a custom middleware for API key authentication. This middleware checks for a valid 'x-api-key' header before allowing access to protected routes. ```javascript const Fastify = require('fastify') const expressPlugin = require('@fastify/express') const fastify = Fastify() const VALID_API_KEY = 'my-secret-api-key-12345' await fastify.register(expressPlugin) // API key validation middleware fastify.use('/api', (req, res, next) => { const apiKey = req.headers['x-api-key'] if (!apiKey || apiKey !== VALID_API_KEY) { res.statusCode = 401 res.end(JSON.stringify({ error: 'Invalid API key' })) return } next() }) fastify.get('/api/protected', async () => { return { data: 'sensitive' } }) await fastify.listen({ port: 3000 }) ``` -------------------------------- ### Access Express Application Instance Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/README.md Access the underlying Express Application instance via the `fastify.express` property. ```javascript fastify.express // Express Application instance ``` -------------------------------- ### Store Data in Fastify Request via Proxy Handler Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/examples.md This example demonstrates how to store custom data (like metadata) directly into the Fastify request object using the Express proxy handler's 'set' trap. This allows Express middleware to set properties that are then accessible on the Fastify request object. ```javascript const Fastify = require('fastify') const expressPlugin = require('@fastify/express') const fastify = Fastify() await fastify.register(expressPlugin, { createProxyHandler: (fastifyReq) => ({ set(target, prop, value) { // Store custom properties in Fastify request if (prop === 'metadata') { fastifyReq.metadata = value return true } return Reflect.set(target, prop, value) }, get(target, prop) { if (prop === 'metadata') { return fastifyReq.metadata } return target[prop] } }) }) fastify.use((req, res, next) => { req.metadata = { timestamp: new Date(), route: req.url } next() }) fastify.get('/', async (request) => { // Access metadata set by middleware return { metadata: request.metadata } }) await fastify.listen({ port: 3000 }) ``` -------------------------------- ### Using Logger Instance in Middleware and Route Handlers Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/request-response-enhancement.md Illustrates accessing the same logger instance via `req.log`, `res.log`, or `request.log` in both Express middleware and Fastify route handlers for consistent logging. ```javascript fastify.use((req, res, next) => { // Access logger via both req and res const logger = req.log // or res.log (same instance) logger.info('Processing') next() }) fastify.get('/data', (request, reply) => { // Access via request.log request.log.info('Handling request') return { data: 'value' } }) ``` -------------------------------- ### Instance Properties: fastify.express Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/README.md Access the underlying Express Application instance through the `fastify.express` property. This can be useful for advanced configurations or direct interaction with Express. ```APIDOC ## Instance Properties: `fastify.express` ### Description Provides access to the Express Application instance managed by the `@fastify/express` plugin. ### Property `fastify.express` ### Type `Express.Application` ### Usage Example ```javascript const expressApp = fastify.express; // Now you can use expressApp for direct Express operations if needed. ``` ``` -------------------------------- ### Register an Express Router Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/middleware-patterns.md Register Express Router instances with Fastify. Handlers within the router will be prefixed with the specified mount path. ```javascript const fastify = Fastify() const express = require('express') const router = express.Router() // Configure router router.get('/users', (req, res) => { res.json([{ id: 1, name: 'John' }]) }) await fastify.register(expressPlugin) fastify.use('/api', router) // Mount under /api ``` -------------------------------- ### Basic Middleware Usage Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/README.md Use this snippet to register a simple Express middleware that logs the HTTP method and URL of incoming requests. Ensure `fastify.use` is called before your routes. ```javascript fastify.use((req, res, next) => { console.log(`${req.method} ${req.url}`) next() }) ``` -------------------------------- ### Using Fastify Logger in Response Context Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/request-response-enhancement.md The `reply.raw.log` property provides access to Fastify's Pino logger instance, allowing you to log messages with automatic request context within response handlers. ```javascript fastify.use((req, res, next) => { res.log.info('Response handler executing') next() }) ``` -------------------------------- ### Accessing the Express Application Instance Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/api-reference.md Provides direct access to the underlying Express application object, allowing for Express-specific configurations, middleware registration, and route handling. ```APIDOC ## Instance Properties ### fastify.express Provides access to the Express application object. Can be used to configure Express-specific settings and to directly register Express middleware or routes. **Type:** `express.Application` **Example:** ```javascript const fastify = Fastify() await fastify.register(expressPlugin) // Disable the x-powered-by header fastify.express.disable('x-powered-by') // Check if a setting is disabled const isPoweredByDisabled = fastify.express.disabled('x-powered-by') // true // Access Express router const router = fastify.express._router // Register Express routes directly (not recommended for new code) fastify.express.get('/legacy', (req, res) => { res.json({ legacy: true }) }) ``` ``` -------------------------------- ### Registering @fastify/express and using Express Middleware Source: https://github.com/fastify/fastify-express/blob/main/README.md Register the @fastify/express plugin and then use Express middleware like 'cors'. The express.Application is also accessible for configuration. ```js const Fastify = require('fastify') async function build () { const fastify = Fastify() await fastify.register(require('@fastify/express')) // do you know we also have cors support? // https://github.com/fastify/fastify-cors fastify.use(require('cors')()) // express.Application is also accessible fastify.express.disabled('x-powered-by') // true return fastify } build() .then(fastify => fastify.listen({ port: 3000 })) .catch(console.log) ``` -------------------------------- ### Static File Serving Middleware with express-plugin Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/middleware-patterns.md Serves static files from a specified directory. The '@fastify/static' plugin offers better Fastify integration. ```javascript const path = require('path') const serveStatic = require('serve-static') fastify.use('/public', serveStatic(path.join(__dirname, 'public'))) ``` -------------------------------- ### Chain Express Middleware Registration Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/middleware-patterns.md Chain multiple `use()` calls for fluent configuration of Express middleware. Middleware executes in the order of registration, so dependencies must be registered sequentially. ```javascript const fastify = Fastify() await fastify.register(expressPlugin) fastify .use(cors()) .use(helmet()) .use(express.json()) .use('/api', (req, res, next) => { // API-specific middleware next() }) ``` ```javascript fastify .use(express.json()) // Parse body first .use((req, res, next) => { // Then use it console.log(req.body) next() }) ``` -------------------------------- ### Template for Custom Fastify Middleware Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/middleware-patterns.md A basic template for creating custom middleware functions in Fastify. Remember to include the `next()` call to pass control to the subsequent middleware or route handler. ```javascript function myMiddleware(options = {}) { return (req, res, next) => { // Middleware logic here console.log('Middleware executing') // Don't forget to call next() next() } } fastify.use(myMiddleware({ option: 'value' })) ``` -------------------------------- ### fastify.use() Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/api-reference.md Registers Express middleware or a middleware chain with optional path restrictions. This method is chainable and allows for flexible integration of Express middleware into Fastify applications. ```APIDOC ## fastify.use() ### Description Registers Express-compatible middleware with the Fastify instance. Middleware can be applied globally or to specific paths, and it executes during the `onRequest` hook. ### Method ``` function use(path?: string | string[] | RequestHandler | RequestHandler[], fn?: RequestHandler | RequestHandler[]) ``` ### Parameters #### Path Parameters - **path** (string | string[] | RequestHandler | RequestHandler[]) - Optional - URL path(s) to restrict middleware execution, or the middleware function itself if `fn` is omitted. - **fn** (RequestHandler | RequestHandler[]) - Optional - Express middleware function(s) to execute. ### Overloads 1. `use(middleware)` - Register middleware for all paths. 2. `use(path, middleware)` - Register middleware for specific path(s). 3. `use([path1, path2], middleware)` - Register middleware for multiple specific paths. ### Return Type FastifyInstance (chainable) ### Example ```javascript // Register middleware for all paths fastify.use(cors()) // Register middleware for specific path fastify.use('/api', cors()) // Register middleware for multiple paths fastify.use(['/api', '/admin'], (req, res, next) => { res.setHeader('x-custom', 'value') next() }) ``` ### Execution Order Middleware executes in registration order during the `onRequest` hook phase, before Fastify route handlers. ``` -------------------------------- ### Query String Separation (Semicolon Delimiter) Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/url-normalization.md Illustrates query string separation when `useSemicolonDelimiter` is set to true, using a semicolon as the delimiter. ```text Input: /path;query=value Path: /path Query: ?query=value ``` -------------------------------- ### Restricting Middleware Execution to Specific Paths Source: https://github.com/fastify/fastify-express/blob/main/README.md Configure middleware to execute only for specific paths using 'fastify.use' with path parameters. Supports single paths, wildcard paths, and multiple paths. ```js const fastify = require('fastify')() const path = require('node:path') const serveStatic = require('serve-static') fastify .register(require('@fastify/express')) .register(subsystem) async function subsystem (fastify, opts) { // Single path fastify.use('/css', serveStatic(path.join(__dirname, '/assets'))) // Wildcard path fastify.use('/css/*', serveStatic(path.join(__dirname, '/assets'))) // Multiple paths fastify.use(['/css', '/js'], serveStatic(path.join(__dirname, '/assets'))) } ``` -------------------------------- ### Registering Express Plugin and Middleware Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/middleware-patterns.md Ensure the Express plugin is registered and awaited before registering middleware. This prevents middleware from being ignored. ```javascript await fastify.register(expressPlugin) // Must await or use .after() fastify.use(middleware) // Register after plugin ``` -------------------------------- ### Custom Logging Middleware Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/middleware-patterns.md A custom middleware for logging request details and duration. Fastify's built-in logging via `fastify.log` is generally preferred. ```javascript fastify.use((req, res, next) => { const start = Date.now() res.on('finish', () => { const duration = Date.now() - start console.log(`${req.method} ${req.url} ${res.statusCode} ${duration}ms`) }) next() }) ``` -------------------------------- ### TypeScript Configuration for require() Imports Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/configuration.md When importing the plugin using require(), ensure your tsconfig.json includes the '@fastify/express' type. This enables TypeScript to recognize the 'use' and 'express' properties added to FastifyInstance. ```json { "compilerOptions": { "types": ["@fastify/express"] } } ``` -------------------------------- ### Fastify URL Normalization Process Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/url-normalization.md Illustrates the internal function used for normalizing URLs in Fastify. It handles path and query separation, and optionally removes duplicate slashes. ```javascript function normalizeUrl(url, options) { const { ignoreDuplicateSlashes, useSemicolonDelimiter } = options // Step 1: Separate path and query const { path, query } = splitPathAndQuery(url, useSemicolonDelimiter) // Step 2: Optionally remove duplicate slashes const normalizedPath = ignoreDuplicateSlashes ? removeDuplicateSlashes(path) : path // Step 3: Reassemble with query string return normalizedPath + query } ``` -------------------------------- ### Using Express Types in Middleware Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/types.md Demonstrates how to import and use Express types like RequestHandler, Request, and Response within a middleware function. This is useful for defining custom middleware that integrates with Fastify. ```typescript import { Application, Request, Response, RequestHandler } from 'express' // Use in middleware const myMiddleware: RequestHandler = (req: Request, res: Response) => { res.send('OK') } ``` -------------------------------- ### Internal Middleware Registry Structure Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/module-structure.md Illustrates the data structure used to store registered middleware per Fastify instance using a private symbol. ```javascript fastify[kMiddlewares] = [ [path1, middleware1], [path2, middleware2], // ... more middleware ] ``` -------------------------------- ### Direct Property Access in Express Middleware Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/request-response-enhancement.md Demonstrates direct access to Fastify-enhanced properties like `id`, `ip`, and `log` within Express middleware for logging and conditional logic. ```javascript fastify.use((req, res, next) => { // Direct property access const id = req.id const ip = req.ip const log = req.log // Use in logging log.info({ ip, id }, 'Incoming request') // Conditional logic if (ip === '127.0.0.1') { // Local request } next() }) ``` -------------------------------- ### Middleware Chain with Multiple Handlers in Fastify Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/examples.md Implement a sequence of Express-style middleware functions in Fastify for tasks like request timing, authentication, and header manipulation. Each handler must call `next()` to proceed. ```javascript const Fastify = require('fastify') const expressPlugin = require('@fastify/express') const fastify = Fastify() await fastify.register(expressPlugin) // Request timing fastify.use((req, res, next) => { req._startTime = Date.now() next() }) // Authentication check fastify.use((req, res, next) => { const token = req.headers.authorization?.split(' ')[1] if (!token) { res.statusCode = 401 res.end(JSON.stringify({ error: 'Unauthorized' })) return } next() }) // Add headers fastify.use((req, res, next) => { res.setHeader('x-processed', 'true') next() }) fastify.get('/', async (request) => { return { message: 'All middleware executed' } }) await fastify.listen({ port: 3000 }) ``` -------------------------------- ### FastifyExpressOptions Interface Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/types.md Defines the configuration options for the @fastify/express plugin. Use this to customize the plugin's behavior, such as the Fastify lifecycle hook for executing Express middleware. ```typescript interface FastifyExpressOptions { expressHook?: string createProxyHandler?: (fastifyReq: FastifyRequest) => ProxyHandler } ``` -------------------------------- ### Register @fastify/express Plugin Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/api-reference.md Register the @fastify/express plugin with a Fastify instance. Use default options for basic Express compatibility or provide custom options to control middleware execution hook and proxy handler. ```javascript const Fastify = require('fastify') const expressPlugin = require('@fastify/express') const fastify = Fastify() // Register with default options await fastify.register(expressPlugin) // Register with custom options await fastify.register(expressPlugin, { expressHook: 'preHandler', createProxyHandler: (fastifyReq) => ({ get(target, prop) { return target[prop] } }) }) ``` -------------------------------- ### Register an Express Application Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/middleware-patterns.md Register an entire Express application with Fastify. This is useful for gradual migration from Express to Fastify. ```javascript const fastify = Fastify() const express = require('express') const app = express() // Configure Express app app.use(express.json()) app.get('/hello', (req, res) => { res.json({ hello: 'world' }) }) await fastify.register(expressPlugin) fastify.use(app) // Mount Express app ``` -------------------------------- ### Registering @fastify/express Plugin Source: https://github.com/fastify/fastify-express/blob/main/_autodocs/README.md Register the @fastify/express plugin with Fastify, providing options for middleware execution. ```typescript import Fastify from 'fastify' import expressPlugin from '@fastify/express' import type { FastifyExpressOptions } from '@fastify/express' const fastify = Fastify() const options: FastifyExpressOptions = { expressHook: 'onRequest', createProxyHandler: (fastifyReq) => ({ get(target, prop) { return target[prop] } }) } await fastify.register(expressPlugin, options) ```