CoolFace
Apppublic

strong-tie/inbound-calls

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
TypeScript.md1608 linesDownload Raw Back to Reference
1<h1 align="center">Fastify</h1>2 3## TypeScript4 5The Fastify framework is written in vanilla JavaScript, and as such type6definitions are not as easy to maintain; however, since version 2 and beyond,7maintainers and contributors have put in a great effort to improve the types.8 9The type system was changed in Fastify version 3. The new type system introduces10generic constraining and defaulting, plus a new way to define schema types such11as a request body, querystring, and more! As the team works on improving12framework and type definition synergy, sometimes parts of the API will not be13typed or may be typed incorrectly. We encourage you to **contribute** to help us14fill in the gaps. Just make sure to read our15[`CONTRIBUTING.md`](https://github.com/fastify/fastify/blob/main/CONTRIBUTING.md)16file before getting started to make sure things go smoothly!17 18> The documentation in this section covers Fastify version 3.x typings19 20> Plugins may or may not include typings. See [Plugins](#plugins) for more21> information. We encourage users to send pull requests to improve typings22> support.23 24๐Ÿšจ Don't forget to install `@types/node`25 26## Learn By Example27 28The best way to learn the Fastify type system is by example! The following four29examples should cover the most common Fastify development cases. After the30examples there is further, more detailed documentation for the type system.31 32### Getting Started33 34This example will get you up and running with Fastify and TypeScript. It results35in a blank http Fastify server.36 371. Create a new npm project, install Fastify, and install typescript & Node.js38   types as peer dependencies:39  ```bash40  npm init -y41  npm i fastify42  npm i -D typescript @types/node43  ```442. Add the following lines to the `"scripts"` section of the `package.json`:45  ```json46  {47    "scripts": {48      "build": "tsc -p tsconfig.json",49      "start": "node index.js"50    }51  }52  ```53 543. Initialize a TypeScript configuration file:55  ```bash56  npx tsc --init57  ```58  or use one of the [recommended59  ones](https://github.com/tsconfig/bases#node-14-tsconfigjson).60 61*Note: Set `target` property in `tsconfig.json` to `es2017` or greater to avoid62[FastifyDeprecation](https://github.com/fastify/fastify/issues/3284) warning.*63 644. Create an `index.ts` file - this will contain the server code655. Add the following code block to your file:66   ```typescript67   import fastify from 'fastify'68 69   const server = fastify()70 71   server.get('/ping', async (request, reply) => {72     return 'pong\n'73   })74 75   server.listen({ port: 8080 }, (err, address) => {76     if (err) {77       console.error(err)78       process.exit(1)79     }80     console.log(`Server listening at ${address}`)81   })82   ```836. Run `npm run build` - this will compile `index.ts` into `index.js` which can84   be executed using Node.js. If you run into any errors please open an issue in85   [fastify/help](https://github.com/fastify/help/)867. Run `npm run start` to run the Fastify server878. You should see `Server listening at http://127.0.0.1:8080` in your console889. Try out your server using `curl localhost:8080/ping`, it should return `pong`89   ๐Ÿ“90 91๐ŸŽ‰ You now have a working Typescript Fastify server! This example demonstrates92the simplicity of the version 3.x type system. By default, the type system93assumes you are using an `http` server. The later examples will demonstrate how94to create more complex servers such as `https` and `http2`, how to specify route95schemas, and more!96 97> For more examples on initializing Fastify with TypeScript (such as enabling98> HTTP2) check out the detailed API section [here][Fastify]99 100### Using Generics101 102The type system heavily relies on generic properties to provide the most103accurate development experience. While some may find the overhead a bit104cumbersome, the tradeoff is worth it! This example will dive into implementing105generic types for route schemas and the dynamic properties located on the106route-level `request` object.107 1081. If you did not complete the previous example, follow steps 1-4 to get set up.1092. Inside `index.ts`, define three interfaces `IQuerystring`,`IHeaders` and `IReply`:110   ```typescript111   interface IQuerystring {112     username: string;113     password: string;114   }115 116   interface IHeaders {117     'h-Custom': string;118   }119 120   interface IReply {121     200: { success: boolean };122     302: { url: string };123     '4xx': { error: string };124   }125   ```1263. Using the three interfaces, define a new API route and pass them as generics.127   The shorthand route methods (i.e. `.get`) accept a generic object128   `RouteGenericInterface` containing five named properties: `Body`,129   `Querystring`, `Params`, `Headers` and `Reply`. The interfaces `Body`,130   `Querystring`, `Params` and `Headers` will be passed down through the route131   method into the route method handler `request` instance and the `Reply`132   interface to the `reply` instance.133   ```typescript134   server.get<{135     Querystring: IQuerystring,136     Headers: IHeaders,137     Reply: IReply138   }>('/auth', async (request, reply) => {139     const { username, password } = request.query140     const customerHeader = request.headers['h-Custom']141     // do something with request data142 143     // chaining .statusCode/.code calls with .send allows type narrowing. For example:144     // this works145     reply.code(200).send({ success: true });146     // but this gives a type error147     reply.code(200).send('uh-oh');148     // it even works for wildcards149     reply.code(404).send({ error: 'Not found' });150     return `logged in!`151   })152   ```153 1544. Build and run the server code with `npm run build` and `npm run start`1555. Query the API156   ```bash157   curl localhost:8080/auth?username=admin&password=Password123!158   ```159   And it should return back `logged in!`1606. But wait there's more! The generic interfaces are also available inside route161   level hook methods. Modify the previous route by adding a `preValidation`162   hook:163   ```typescript164   server.get<{165     Querystring: IQuerystring,166     Headers: IHeaders,167     Reply: IReply168   }>('/auth', {169     preValidation: (request, reply, done) => {170       const { username, password } = request.query171       done(username !== 'admin' ? new Error('Must be admin') : undefined) // only validate `admin` account172     }173   }, async (request, reply) => {174     const customerHeader = request.headers['h-Custom']175     // do something with request data176     return `logged in!`177   })178   ```1797. Build and run and query with the `username` query string option set to180   anything other than `admin`. The API should now return a HTTP 500 error181   `{"statusCode":500,"error":"Internal Server Error","message":"Must be182   admin"}`183 184๐ŸŽ‰ Good work, now you can define interfaces for each route and have strictly185typed request and reply instances. Other parts of the Fastify type system rely186on generic properties. Make sure to reference the detailed type system187documentation below to learn more about what is available.188 189### JSON Schema190 191To validate your requests and responses you can use JSON Schema files. If you192didn't know already, defining schemas for your Fastify routes can increase their193throughput! Check out the [Validation and194Serialization](./Validation-and-Serialization.md) documentation for more info.195 196Also it has the advantage to use the defined type within your handlers197(including pre-validation, etc.).198 199Here are some options on how to achieve this.200 201#### Fastify Type Providers202 203Fastify offers two packages wrapping `json-schema-to-ts` and `typebox`:204 205- [`@fastify/type-provider-json-schema-to-ts`](https://github.com/fastify/fastify-type-provider-json-schema-to-ts)206- [`@fastify/type-provider-typebox`](https://github.com/fastify/fastify-type-provider-typebox)207 208And a `zod` wrapper by a third party called [`fastify-type-provider-zod`](https://github.com/turkerdev/fastify-type-provider-zod)209 210They simplify schema validation setup and you can read more about them in [Type211Providers](./Type-Providers.md) page.212 213Below is how to setup schema validation using the `typebox`,214`json-schema-to-typescript`, and `json-schema-to-ts` packages without type215providers.216 217#### TypeBox218 219A useful library for building types and a schema at once is [TypeBox](https://www.npmjs.com/package/@sinclair/typebox).220With TypeBox you define your schema within your code and use them directly as221types or schemas as you need them.222 223When you want to use it for validation of some payload in a fastify route you224can do it as follows:225 2261. Install `typebox` in your project.227 228    ```bash229    npm i @sinclair/typebox230    ```231 2322. Define the schema you need with `Type` and create the respective type  with233   `Static`.234 235    ```typescript236    import { Static, Type } from '@sinclair/typebox'237 238    export const User = Type.Object({239      name: Type.String(),240      mail: Type.Optional(Type.String({ format: 'email' })),241    })242 243    export type UserType = Static<typeof User>244    ```245 2463. Use the defined type and schema during the definition of your route247 248    ```typescript249    import Fastify from 'fastify'250    // ...251 252    const fastify = Fastify()253 254    fastify.post<{ Body: UserType, Reply: UserType }>(255      '/',256      {257        schema: {258          body: User,259          response: {260            200: User261          },262        },263      },264      (request, reply) => {265        // The `name` and `mail` types are automatically inferred266        const { name, mail } = request.body;267        reply.status(200).send({ name, mail });268      }269    )270    ```271 272#### json-schema-to-typescript273 274In the last example we used Typebox to define the types and schemas for our275route. Many users will already be using JSON Schemas to define these properties,276and luckily there is a way to transform existing JSON Schemas into TypeScript277interfaces!278 2791. If you did not complete the 'Getting Started' example, go back and follow280   steps 1-4 first.2812. Install the `json-schema-to-typescript` module:282 283   ```bash284   npm i -D json-schema-to-typescript285   ```286 2873. Create a new folder called `schemas` and add two files `headers.json` and288   `querystring.json`. Copy and paste the following schema definitions into the289   respective files:290 291   ```json292   {293     "title": "Headers Schema",294     "type": "object",295     "properties": {296       "h-Custom": { "type": "string" }297     },298     "additionalProperties": false,299     "required": ["h-Custom"]300   }301   ```302 303   ```json304   {305     "title": "Querystring Schema",306     "type": "object",307     "properties": {308       "username": { "type": "string" },309       "password": { "type": "string" }310     },311     "additionalProperties": false,312     "required": ["username", "password"]313   }314   ```315 3164. Add a `compile-schemas` script to the package.json:317 318```json319   {320     "scripts": {321       "compile-schemas": "json2ts -i schemas -o types"322     }323   }324```325 326   `json2ts` is a CLI utility included in `json-schema-to-typescript`. `schemas`327   is the input path, and `types` is the output path.3285. Run `npm run compile-schemas`. Two new files should have been created in the329   `types` directory.3306. Update `index.ts` to have the following code:331 332```typescript333   import fastify from 'fastify'334 335   // import json schemas as normal336   import QuerystringSchema from './schemas/querystring.json'337   import HeadersSchema from './schemas/headers.json'338 339   // import the generated interfaces340   import { QuerystringSchema as QuerystringSchemaInterface } from './types/querystring'341   import { HeadersSchema as HeadersSchemaInterface } from './types/headers'342 343   const server = fastify()344 345   server.get<{346     Querystring: QuerystringSchemaInterface,347     Headers: HeadersSchemaInterface348   }>('/auth', {349     schema: {350       querystring: QuerystringSchema,351       headers: HeadersSchema352     },353     preValidation: (request, reply, done) => {354       const { username, password } = request.query355       done(username !== 'admin' ? new Error('Must be admin') : undefined)356     }357     //  or if using async358     //  preValidation: async (request, reply) => {359     //    const { username, password } = request.query360     //    if (username !== "admin") throw new Error("Must be admin");361     //  }362   }, async (request, reply) => {363     const customerHeader = request.headers['h-Custom']364     // do something with request data365     return `logged in!`366   })367 368   server.route<{369     Querystring: QuerystringSchemaInterface,370     Headers: HeadersSchemaInterface371   }>({372     method: 'GET',373     url: '/auth2',374     schema: {375       querystring: QuerystringSchema,376       headers: HeadersSchema377     },378     preHandler: (request, reply, done) => {379       const { username, password } = request.query380       const customerHeader = request.headers['h-Custom']381       done()382     },383     handler: (request, reply) => {384       const { username, password } = request.query385       const customerHeader = request.headers['h-Custom']386       reply.status(200).send({username});387     }388   })389 390   server.listen({ port: 8080 }, (err, address) => {391     if (err) {392       console.error(err)393       process.exit(0)394     }395     console.log(`Server listening at ${address}`)396   })397   ```398   Pay special attention to the imports at the top of this file. It might seem399   redundant, but you need to import both the schema files and the generated400   interfaces.401 402Great work! Now you can make use of both JSON Schemas and TypeScript403definitions.404 405#### json-schema-to-ts406 407If you do not want to generate types from your schemas, but want to use them408directly from your code, you can use the package409[json-schema-to-ts](https://www.npmjs.com/package/json-schema-to-ts).410 411You can install it as dev-dependency.412 413```bash414npm i -D json-schema-to-ts415```416 417In your code you can define your schema like a normal object. But be aware of418making it *const* like explained in the docs of the module.419 420```typescript421const todo = {422  type: 'object',423  properties: {424    name: { type: 'string' },425    description: { type: 'string' },426    done: { type: 'boolean' },427  },428  required: ['name'],429} as const; // don't forget to use const !430```431 432With the provided type `FromSchema` you can build a type from your schema and433use it in your handler.434 435```typescript436import { FromSchema } from "json-schema-to-ts";437fastify.post<{ Body: FromSchema<typeof todo> }>(438  '/todo',439  {440    schema: {441      body: todo,442      response: {443        201: {444          type: 'string',445        },446      },447    }448  },449  async (request, reply): Promise<void> => {450 451    /*452    request.body has type453    {454      [x: string]: unknown;455      description?: string;456      done?: boolean;457      name: string;458    }459    */460 461    request.body.name // will not throw type error462    request.body.notthere // will throw type error463 464    reply.status(201).send();465  },466);467```468 469### Plugins470 471One of Fastify's most distinguishable features is its extensive plugin472ecosystem. Plugin types are fully supported, and take advantage of the473[declaration474merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html)475pattern. This example is broken up into three parts: Creating a TypeScript476Fastify Plugin, Creating Type Definitions for a Fastify Plugin, and Using a477Fastify Plugin in a TypeScript Project.478 479#### Creating a TypeScript Fastify Plugin480 4811. Initialize a new npm project and install required dependencies482   ```bash483   npm init -y484   npm i fastify fastify-plugin485   npm i -D typescript @types/node486   ```4872. Add a `build` script to the `"scripts"` section and `'index.d.ts'` to the488   `"types"` section of the `package.json` file:489   ```json490   {491     "types": "index.d.ts",492     "scripts": {493       "build": "tsc -p tsconfig.json"494     }495   }496   ```4973. Initialize a TypeScript configuration file:498   ```bash499   npx typescript --init500   ```501   Once the file is generated, enable the `"declaration"` option in the502   `"compilerOptions"` object.503   ```json504   {505     "compilerOptions": {506       "declaration": true507     }508   }509   ```5104. Create an `index.ts` file - this will contain the plugin code5115. Add the following code to `index.ts`512   ```typescript513   import { FastifyPluginCallback, FastifyPluginAsync } from 'fastify'514   import fp from 'fastify-plugin'515 516   // using declaration merging, add your plugin props to the appropriate fastify interfaces517   // if prop type is defined here, the value will be typechecked when you call decorate{,Request,Reply}518   declare module 'fastify' {519     interface FastifyRequest {520       myPluginProp: string521     }522     interface FastifyReply {523       myPluginProp: number524     }525   }526 527   // define options528   export interface MyPluginOptions {529     myPluginOption: string530   }531 532   // define plugin using callbacks533   const myPluginCallback: FastifyPluginCallback<MyPluginOptions> = (fastify, options, done) => {534     fastify.decorateRequest('myPluginProp', 'super_secret_value')535     fastify.decorateReply('myPluginProp', options.myPluginOption)536 537     done()538   }539 540   // define plugin using promises541   const myPluginAsync: FastifyPluginAsync<MyPluginOptions> = async (fastify, options) => {542     fastify.decorateRequest('myPluginProp', 'super_secret_value')543     fastify.decorateReply('myPluginProp', options.myPluginOption)544   }545 546   // export plugin using fastify-plugin547   export default fp(myPluginCallback, '3.x')548   // or549   // export default fp(myPluginAsync, '3.x')550   ```5516. Run `npm run build` to compile the plugin code and produce both a JavaScript552   source file and a type definition file.5537. With the plugin now complete you can [publish to npm] or use it locally.554   > You do not _need_ to publish your plugin to npm to use it. You can include555   > it in a Fastify project and reference it as you would any piece of code! As556   > a TypeScript user, make sure the declaration override exists somewhere that557   > will be included in your project compilation so the TypeScript interpreter558   > can process it.559 560#### Creating Type Definitions for a Fastify Plugin561 562This plugin guide is for Fastify plugins written in JavaScript. The steps563outlined in this example are for adding TypeScript support for users consuming564your plugin.565 5661. Initialize a new npm project and install required dependencies567   ```bash568   npm init -y569   npm i fastify-plugin570   ```5712. Create two files `index.js` and `index.d.ts`5723. Modify the package json to include these files under the `main` and `types`573   properties (the name does not have to be `index` explicitly, but it is574   recommended the files have the same name):575   ```json576   {577     "main": "index.js",578     "types": "index.d.ts"579   }580   ```5814. Open `index.js` and add the following code:582   ```javascript583   // fastify-plugin is highly recommended for any plugin you write584   const fp = require('fastify-plugin')585 586   function myPlugin (instance, options, done) {587 588     // decorate the fastify instance with a custom function called myPluginFunc589     instance.decorate('myPluginFunc', (input) => {590       return input.toUpperCase()591     })592 593     done()594   }595 596   module.exports = fp(myPlugin, {597     fastify: '5.x',598     name: 'my-plugin' // this is used by fastify-plugin to derive the property name599   })600   ```6015. Open `index.d.ts` and add the following code:602   ```typescript603   import { FastifyPluginCallback } from 'fastify'604 605   interface PluginOptions {606     //...607   }608 609   // Optionally, you can add any additional exports.610   // Here we are exporting the decorator we added.611   export interface myPluginFunc {612     (input: string): string613   }614 615   // Most importantly, use declaration merging to add the custom property to the Fastify type system616   declare module 'fastify' {617     interface FastifyInstance {618       myPluginFunc: myPluginFunc619     }620   }621 622   // fastify-plugin automatically adds named export, so be sure to add also this type623   // the variable name is derived from `options.name` property if `module.exports.myPlugin` is missing624   export const myPlugin: FastifyPluginCallback<PluginOptions>625 626   // fastify-plugin automatically adds `.default` property to the exported plugin. See the note below627   export default myPlugin628   ```629 630__Note__: [fastify-plugin](https://github.com/fastify/fastify-plugin) v2.3.0 and631newer, automatically adds `.default` property and a named export to the exported632plugin. Be sure to `export default` and `export const myPlugin` in your typings633to provide the best developer experience. For a complete example you can check634out635[@fastify/swagger](https://github.com/fastify/fastify-swagger/blob/master/index.d.ts).636 637With those files completed, the plugin is now ready to be consumed by any638TypeScript project!639 640The Fastify plugin system enables developers to decorate the Fastify instance,641and the request/reply instances. For more information check out this blog post642on [Declaration Merging and Generic643Inheritance](https://dev.to/ethanarrowood/is-declaration-merging-and-generic-inheritance-at-the-same-time-impossible-53cp).644 645#### Using a Plugin646 647Using a Fastify plugin in TypeScript is just as easy as using one in JavaScript.648Import the plugin with `import/from` and you're all set -- except there is one649exception users should be aware of.650 651Fastify plugins use declaration merging to modify existing Fastify type652interfaces (check out the previous two examples for more details). Declaration653merging is not very _smart_, meaning if the plugin type definition for a plugin654is within the scope of the TypeScript interpreter, then the plugin types will be655included **regardless** of if the plugin is being used or not. This is an656unfortunate limitation of using TypeScript and is unavoidable as of right now.657 658However, there are a couple of suggestions to help improve this experience:659- Make sure the `no-unused-vars` rule is enabled in660  [ESLint](https://eslint.org/docs/rules/no-unused-vars) and any imported plugin661  are actually being loaded.662- In case you've the `@typescript-eslint/no-floating-promises` enabled,663please double-check that your ESLint configuration includes a `allowForKnownSafePromises`664property as described on the [`typescript-eslint no-floating-promises allowForKnownSafePromises665documentation`](https://typescript-eslint.io/rules/no-floating-promises/#allowforknownsafepromises):666```667{668  "rules": {669    "@typescript-eslint/no-floating-promises": ["error", {670      "allowForKnownSafePromises": [671        { "from": "package", "name": "FastifyInstance", "package": "fastify" },672        { "from": "package", "name": "FastifyReply", "package": "fastify" },673        { "from": "package", "name": "SafePromiseLike", "package": "fastify" },674      ]675    }]676  }677}678```679- Use a module such as [depcheck](https://www.npmjs.com/package/depcheck) or680  [npm-check](https://www.npmjs.com/package/npm-check) to verify plugin681  dependencies are being used somewhere in your project.682 683Note that using `require` will not load the type definitions properly and may684cause type errors.685TypeScript can only identify the types that are directly imported into code,686which means that you can use require inline with import on top. For example:687 688```typescript689import 'plugin' // here will trigger the type augmentation.690 691fastify.register(require('plugin'))692```693 694```typescript695import plugin from 'plugin' //  here will trigger the type augmentation.696 697fastify.register(plugin)698```699 700Or even explicit config on tsconfig701```jsonc702{703  "types": ["plugin"] // we force TypeScript to import the types704}705```706 707## Code Completion In Vanilla JavaScript708 709Vanilla JavaScript can use the published types to provide code completion (e.g.710[Intellisense](https://code.visualstudio.com/docs/editor/intellisense)) by711following the [TypeScript JSDoc712Reference](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html).713 714For example:715 716```js717/**  @type {import('fastify').FastifyPluginAsync<{ optionA: boolean, optionB: string }>} */718module.exports = async function (fastify, { optionA, optionB }) {719  fastify.get('/look', () => 'at me');720}721```722 723## API Type System Documentation724 725This section is a detailed account of all the types available to you in Fastify726version 3.x727 728All `http`, `https`, and `http2` types are inferred from `@types/node`729 730[Generics](#generics) are documented by their default value as well as their731constraint value(s). Read these articles for more information on TypeScript732generics.733- [Generic Parameter734  Default](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-3.html#generic-parameter-defaults)735- [Generic Constraints](https://www.typescriptlang.org/docs/handbook/2/generics.html#generic-constraints)736 737 738#### How to import739 740The Fastify API is powered by the `fastify()` method. In JavaScript you would741import it using `const fastify = require('fastify')`. In TypeScript it is742recommended to use the `import/from` syntax instead so types can be resolved.743There are a couple supported import methods with the Fastify type system.744 7451. `import fastify from 'fastify'`746   - Types are resolved but not accessible using dot notation747   - Example:748     ```typescript749     import fastify from 'fastify'750 751     const f = fastify()752     f.listen({ port: 8080 }, () => { console.log('running') })753     ```754   - Gain access to types with destructuring:755     ```typescript756     import fastify, { FastifyInstance } from 'fastify'757 758     const f: FastifyInstance = fastify()759     f.listen({ port: 8080 }, () => { console.log('running') })760     ```761   - Destructuring also works for the main API method:762     ```typescript763     import { fastify, FastifyInstance } from 'fastify'764 765     const f: FastifyInstance = fastify()766     f.listen({ port: 8080 }, () => { console.log('running') })767     ```7682. `import * as Fastify from 'fastify'`769   - Types are resolved and accessible using dot notation770   - Calling the main Fastify API method requires a slightly different syntax771     (see example)772   - Example:773     ```typescript774     import * as Fastify from 'fastify'775 776     const f: Fastify.FastifyInstance = Fastify.fastify()777     f.listen({ port: 8080 }, () => { console.log('running') })778     ```7793. `const fastify = require('fastify')`780   - This syntax is valid and will import fastify as expected; however, types781     will **not** be resolved782   - Example:783     ```typescript784     const fastify = require('fastify')785 786     const f = fastify()787     f.listen({ port: 8080 }, () => { console.log('running') })788     ```789   - Destructuring is supported and will resolve types properly790     ```typescript791     const { fastify } = require('fastify')792 793     const f = fastify()794     f.listen({ port: 8080 }, () => { console.log('running') })795     ```796 797#### Generics798 799Many type definitions share the same generic parameters; they are all800documented, in detail, within this section.801 802Most definitions depend on `@types/node` modules `http`, `https`, and `http2`803 804##### RawServer805Underlying Node.js server type806 807Default: `http.Server`808 809Constraints: `http.Server`, `https.Server`, `http2.Http2Server`,810`http2.Http2SecureServer`811 812Enforces generic parameters: [`RawRequest`][RawRequestGeneric],813[`RawReply`][RawReplyGeneric]814 815##### RawRequest816Underlying Node.js request type817 818Default: [`RawRequestDefaultExpression`][RawRequestDefaultExpression]819 820Constraints: `http.IncomingMessage`, `http2.Http2ServerRequest`821 822Enforced by: [`RawServer`][RawServerGeneric]823 824##### RawReply825Underlying Node.js response type826 827Default: [`RawReplyDefaultExpression`][RawReplyDefaultExpression]828 829Constraints: `http.ServerResponse`, `http2.Http2ServerResponse`830 831Enforced by: [`RawServer`][RawServerGeneric]832 833##### Logger834Fastify logging utility835 836Default: [`FastifyLoggerOptions`][FastifyLoggerOptions]837 838Enforced by: [`RawServer`][RawServerGeneric]839 840##### RawBody841A generic parameter for the content-type-parser methods.842 843Constraints: `string | Buffer`844 845---846 847#### Fastify848 849##### fastify< [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [Logger][LoggerGeneric]>(opts?: [FastifyServerOptions][FastifyServerOptions]): [FastifyInstance][FastifyInstance]850[src](https://github.com/fastify/fastify/blob/main/fastify.d.ts#L19)851 852The main Fastify API method. By default creates an HTTP server. Utilizing853discriminant unions and overload methods, the type system will automatically854infer which type of server (http, https, or http2) is being created purely based855on the options based to the method (see the examples below for more856information). It also supports an extensive generic type system to allow the857user to extend the underlying Node.js Server, Request, and Reply objects.858Additionally, the `Logger` generic exists for custom log types. See the examples859and generic breakdown below for more information.860 861###### Example 1: Standard HTTP server862 863No need to specify the `Server` generic as the type system defaults to HTTP.864```typescript865import fastify from 'fastify'866 867const server = fastify()868```869Check out the Learn By Example - [Getting Started](#getting-started) example for870a more detailed http server walkthrough.871 872###### Example 2: HTTPS server873 8741. Create the following imports from `@types/node` and `fastify`875   ```typescript876   import fs from 'node:fs'877   import path from 'node:path'878   import fastify from 'fastify'879   ```8802. Perform the following steps before setting up a Fastify HTTPS server881to create the `key.pem` and `cert.pem` files:882```sh883openssl genrsa -out key.pem884openssl req -new -key key.pem -out csr.pem885openssl x509 -req -days 9999 -in csr.pem -signkey key.pem -out cert.pem886rm csr.pem887```8883. Instantiate a Fastify https server and add a route:889   ```typescript890   const server = fastify({891     https: {892       key: fs.readFileSync(path.join(__dirname, 'key.pem')),893       cert: fs.readFileSync(path.join(__dirname, 'cert.pem'))894     }895   })896 897   server.get('/', async function (request, reply) {898     return { hello: 'world' }899   })900 901   server.listen({ port: 8080 }, (err, address) => {902     if (err) {903       console.error(err)904       process.exit(0)905     }906     console.log(`Server listening at ${address}`)907   })908   ```9094. Build and run! Test your server out by querying with: `curl -k910   https://localhost:8080`911 912###### Example 3: HTTP2 server913 914There are two types of HTTP2 server types, insecure and secure. Both require915specifying the `http2` property as `true` in the `options` object. The `https`916property is used for creating a secure http2 server; omitting the `https`917property will create an insecure http2 server.918 919```typescript920const insecureServer = fastify({ http2: true })921const secureServer = fastify({922  http2: true,923  https: {} // use the `key.pem` and `cert.pem` files from the https section924})925```926 927For more details on using HTTP2 check out the Fastify [HTTP2](./HTTP2.md)928documentation page.929 930###### Example 4: Extended HTTP server931 932Not only can you specify the server type, but also the request and reply types.933Thus, allowing you to specify special properties, methods, and more! When934specified at server instantiation, the custom type becomes available on all935further instances of the custom type.936```typescript937import fastify from 'fastify'938import http from 'node:http'939 940interface customRequest extends http.IncomingMessage {941  mySpecialProp: string942}943 944const server = fastify<http.Server, customRequest>()945 946server.get('/', async (request, reply) => {947  const someValue = request.raw.mySpecialProp // TS knows this is a string, because of the `customRequest` interface948  return someValue.toUpperCase()949})950```951 952###### Example 5: Specifying logger types953 954Fastify uses [Pino](https://getpino.io/#/) logging library under the hood. Since955`pino@7`, all of it's properties can be configured via `logger` field when956constructing Fastify's instance. If properties you need aren't exposed, please957open an Issue to [`Pino`](https://github.com/pinojs/pino/issues) or pass a958preconfigured external instance of Pino (or any other compatible logger) as959temporary fix to Fastify via the same field. This allows creating custom960serializers as well, see the [Logging](Logging.md) documentation for more info.961 962```typescript963import fastify from 'fastify'964 965const server = fastify({966  logger: {967    level: 'info',968    redact: ['x-userinfo'],969    messageKey: 'message'970  }971})972 973server.get('/', async (request, reply) => {974  server.log.info('log message')975  return 'another message'976})977```978 979---980 981##### fastify.HTTPMethods982[src](https://github.com/fastify/fastify/blob/main/types/utils.d.ts#L8)983 984Union type of: `'DELETE' | 'GET' | 'HEAD' | 'PATCH' | 'POST' | 'PUT' |985'OPTIONS'`986 987##### fastify.RawServerBase988[src](https://github.com/fastify/fastify/blob/main/types/utils.d.ts#L13)989 990Dependent on `@types/node` modules `http`, `https`, `http2`991 992Union type of: `http.Server | https.Server | http2.Http2Server |993http2.Http2SecureServer`994 995##### fastify.RawServerDefault996[src](https://github.com/fastify/fastify/blob/main/types/utils.d.ts#L18)997 998Dependent on `@types/node` modules `http`999 1000Type alias for `http.Server`1001 1002---1003 1004##### fastify.FastifyServerOptions< [RawServer][RawServerGeneric], [Logger][LoggerGeneric]>1005 1006[src](https://github.com/fastify/fastify/blob/main/fastify.d.ts#L29)1007 1008An interface of properties used in the instantiation of the Fastify server. Is1009used in the main [`fastify()`][Fastify] method. The `RawServer` and `Logger`1010generic parameters are passed down through that method.1011 1012See the main [fastify][Fastify] method type definition section for examples on1013instantiating a Fastify server with TypeScript.1014 1015##### fastify.FastifyInstance< [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RequestGeneric][FastifyRequestGenericInterface], [Logger][LoggerGeneric]>1016 1017[src](https://github.com/fastify/fastify/blob/main/types/instance.d.ts#L16)1018 1019Interface that represents the Fastify server object. This is the returned server1020instance from the [`fastify()`][Fastify] method. This type is an interface so it1021can be extended via [declaration1022merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html)1023if your code makes use of the `decorate` method.1024 1025Through the use of generic cascading, all methods attached to the instance1026inherit the generic properties from instantiation. This means that by specifying1027the server, request, or reply types, all methods will know how to type those1028objects.1029 1030Check out the main [Learn by Example](#learn-by-example) section for detailed1031guides, or the more simplified [fastify][Fastify] method examples for additional1032details on this interface.1033 1034---1035 1036#### Request1037 1038##### fastify.FastifyRequest< [RequestGeneric][FastifyRequestGenericInterface], [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric]>1039[src](https://github.com/fastify/fastify/blob/main/types/request.d.ts#L15)1040 1041This interface contains properties of Fastify request object. The properties1042added here disregard what kind of request object (http vs http2) and disregard1043what route level it is serving; thus calling `request.body` inside a GET request1044will not throw an error (but good luck sending a GET request with a body ๐Ÿ˜‰).1045 1046If you need to add custom properties to the `FastifyRequest` object (such as1047when using the [`decorateRequest`][DecorateRequest] method) you need to use1048declaration merging on this interface.1049 1050A basic example is provided in the [`FastifyRequest`][FastifyRequest] section.1051For a more detailed example check out the Learn By Example section:1052[Plugins](#plugins)1053 1054###### Example1055```typescript1056import fastify from 'fastify'1057 1058const server = fastify()1059 1060server.decorateRequest('someProp', 'hello!')1061 1062server.get('/', async (request, reply) => {1063  const { someProp } = request // need to use declaration merging to add this prop to the request interface1064  return someProp1065})1066 1067// this declaration must be in scope of the typescript interpreter to work1068declare module 'fastify' {1069  interface FastifyRequest { // you must reference the interface and not the type1070    someProp: string1071  }1072}1073 1074// Or you can type your request using1075type CustomRequest = FastifyRequest<{1076  Body: { test: boolean };1077}>1078 1079server.get('/typedRequest', async (request: CustomRequest, reply: FastifyReply) => {1080  return request.body.test1081})1082```1083 1084##### fastify.RequestGenericInterface1085[src](https://github.com/fastify/fastify/blob/main/types/request.d.ts#L4)1086 1087Fastify request objects have four dynamic properties: `body`, `params`, `query`,1088and `headers`. Their respective types are assignable through this interface. It1089is a named property interface enabling the developer to ignore the properties1090they do not want to specify. All omitted properties are defaulted to `unknown`.1091The corresponding property names are: `Body`, `Querystring`, `Params`,1092`Headers`.1093 1094```typescript1095import fastify, { RequestGenericInterface } from 'fastify'1096 1097const server = fastify()1098 1099interface requestGeneric extends RequestGenericInterface {1100  Querystring: {1101    name: string1102  }1103}1104 1105server.get<requestGeneric>('/', async (request, reply) => {1106  const { name } = request.query // the name prop now exists on the query prop1107  return name.toUpperCase()1108})1109```1110 1111If you want to see a detailed example of using this interface check out the1112Learn by Example section: [JSON Schema](#json-schema).1113 1114##### fastify.RawRequestDefaultExpression\<[RawServer][RawServerGeneric]\>1115[src](https://github.com/fastify/fastify/blob/main/types/utils.d.ts#L23)1116 1117Dependent on `@types/node` modules `http`, `https`, `http2`1118 1119Generic parameter `RawServer` defaults to [`RawServerDefault`][RawServerDefault]1120 1121If `RawServer` is of type `http.Server` or `https.Server`, then this expression1122returns `http.IncomingMessage`, otherwise, it returns1123`http2.Http2ServerRequest`.1124 1125```typescript1126import http from 'node:http'1127import http2 from 'node:http2'1128import { RawRequestDefaultExpression } from 'fastify'1129 1130RawRequestDefaultExpression<http.Server> // -> http.IncomingMessage1131RawRequestDefaultExpression<http2.Http2Server> // -> http2.Http2ServerRequest1132```1133 1134---1135 1136#### Reply1137 1138##### fastify.FastifyReply<[RequestGeneric][FastifyRequestGenericInterface], [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [ContextConfig][ContextConfigGeneric]>1139[src](https://github.com/fastify/fastify/blob/main/types/reply.d.ts#L32)1140 1141This interface contains the custom properties that Fastify adds to the standard1142Node.js reply object. The properties added here disregard what kind of reply1143object (http vs http2).1144 1145If you need to add custom properties to the FastifyReply object (such as when1146using the `decorateReply` method) you need to use declaration merging on this1147interface.1148 1149A basic example is provided in the [`FastifyReply`][FastifyReply] section. For a1150more detailed example check out the Learn By Example section:1151[Plugins](#plugins)1152 1153###### Example1154```typescript1155import fastify from 'fastify'1156 1157const server = fastify()1158 1159server.decorateReply('someProp', 'world')1160 1161server.get('/', async (request, reply) => {1162  const { someProp } = reply // need to use declaration merging to add this prop to the reply interface1163  return someProp1164})1165 1166// this declaration must be in scope of the typescript interpreter to work1167declare module 'fastify' {1168  interface FastifyReply { // you must reference the interface and not the type1169    someProp: string1170  }1171}1172```1173 1174##### fastify.RawReplyDefaultExpression< [RawServer][RawServerGeneric]>1175[src](https://github.com/fastify/fastify/blob/main/types/utils.d.ts#L27)1176 1177Dependent on `@types/node` modules `http`, `https`, `http2`1178 1179Generic parameter `RawServer` defaults to [`RawServerDefault`][RawServerDefault]1180 1181If `RawServer` is of type `http.Server` or `https.Server`, then this expression1182returns `http.ServerResponse`, otherwise, it returns1183`http2.Http2ServerResponse`.1184 1185```typescript1186import http from 'node:http'1187import http2 from 'node:http2'1188import { RawReplyDefaultExpression } from 'fastify'1189 1190RawReplyDefaultExpression<http.Server> // -> http.ServerResponse1191RawReplyDefaultExpression<http2.Http2Server> // -> http2.Http2ServerResponse1192```1193 1194---1195 1196#### Plugin1197 1198Fastify allows the user to extend its functionalities with plugins. A plugin can1199be a set of routes, a server decorator or whatever. To activate plugins, use the1200[`fastify.register()`][FastifyRegister] method.

Showing the first 1,200 of 1608 lines. Download the file for the rest.