Framework guides
Fastify
Set up Featurevisor SDK instance in a Fastify application using a custom decorator, including TypeScript integration for evaluating feature flags.
Hello World application#
Before going into Featurevisor integration, let's create a simple Hello World Fastify application.
We start by installing the package:
$ npm install --save fastify// index.jsconst fastify = require('fastify')({ logger: true })const PORT = 3000fastify.get('/', async (request, reply) => { return 'Hello World!'})fastify.listen(PORT, () => { console.log(`Example app listening on port ${PORT}`)})We can start the server with this command:
$ node index.jsExample app listening on port 3000Featurevisor integration#
We install the Featurevisor SDK first:
$ npm install --save @featurevisor/sdkWe can now create an instance of the SDK and use it in our application:
// Require the fastify framework and instantiate itconst fastify = require('fastify')({ logger: true,})// Featurevisor SDKconst { createFeaturevisor } = require('@featurevisor/sdk')const DATAFILE_URL = 'https://featurevisor-example-cloudflare.pages.dev/production/featurevisor-all.json' // replace with yoursite cdnconst f = createFeaturevisor({})// Declare a routefastify.get('/', async (request, reply) => { const featureKey = 'my_feature' const context = { userId: '123', country: 'nl' } const isEnabled = f.isEnabled(featureKey, context) if (isEnabled) { reply.send('Hello World!') } else { reply.send('Not enabled yet!') }})// Run the server!const start = async () => { const datafile = await fetch(DATAFILE_URL).then((res) => res.json()) f.setDatafile(datafile, true) // we start the server only after the datafile is loaded fastify.listen({ port: 3000 }, function (err, address) { if (err) { fastify.log.error(err) process.exit(1) } fastify.log.info(`server listening on ${fastify.server.address().port}`) })}start()To keep the datafile fresh without restarting the server, fetch it again on an interval and call f.setDatafile(datafile, true) to replace the previously loaded full datafile. See more in the JavaScript SDK page.
Decorator#
It is very unlikely that we will have all our routes defined in the same index.js file, making it difficult for us to use the same Featurevisor SDK instance in all of them.
To solve this problem, we can create a custom decorator that will set the Featurevisor SDK instance to the request object, so that we can use the same instance in all our routes throughout the lifecycle of this application.
// index.js// ...fastify.decorateRequest('f', f)// ...Now from anywhere in our application (either in index.js or some other module), we can access the Featurevisor SDK instance via request.f:
fastify.get('/my-route', async (request, reply) => { const featureKey = 'my_feature' const context = { userId: '123', country: 'nl' } const isEnabled = request.f.isEnabled(featureKey, context) if (isEnabled) { reply.send('Hello World!') } else { reply.send('Not enabled yet!') }})TypeScript usage#
If you are using TypeScript, you can extend the Request interface to add the f property for Featurevisor SDK's instance.
Create a new custom.d.ts file and make sure to add it in tsconfig.json's files section:
import type { Featurevisor } from '@featurevisor/sdk'import type { FastifyInstance } from 'fastify'declare module 'fastify' { interface FastifyInstance { f: Featurevisor }}Working repository#
You can find a fully functional example of this integration on GitHub: https://github.com/featurevisor/featurevisor-example-fastify.

