fastify-cli

repository·main·Indexed 20 days ago

https://github.com/fastify/fastify-cli

Command line tools to generate, write, and run Fastify applications. Version 8.0.0 provides a single interface for tasks including starting a server, scaffolding new projects and plugins via `generate` and `generate-plugin`, generating Swagger/OpenAPI schemas, and creating plugin READMEs. It includes a helper module for loading application instances during testing and supports CommonJS, Async/Await, and ESM plugin formats.

Tokens
11.7K
Snippets
38
Records
48
Agent score
71%

What's inside fastify-cli

  1. Use the fastify CLI to manage your project

    main

    The fastify command provides a single interface for common Fastify tasks. You can view all available commands and their descriptions by running fastify or fastify help.

    Available Commands:

    • start: Start a Fastify server.
    • eject: Convert your application into a standalone executable by adding a server.js or server.ts file.
    • generate: Scaffold a new Fastify project.
    • generate-plugin: Scaffold a new plugin project.
    • generate-swagger: Generate Swagger/OpenAPI schemas (requires @fastify/swagger).
    • readme: Generate a README.md for a plugin.
    • print-routes: Debug the internal radix tree used by the router.
    • print-plugins: Debug the internal plugin tree used by avvio.
    • version: Show the current fastify-cli version.
    • help: Show help about commands.
    $ fastify
  2. Organize application routes using the modular monolith pattern

    main

    The routes folder is used to define the endpoints of your web application. Following a modular monolith approach, you should organize routes into distinct, self-contained modules. This structure facilitates easier scaling and allows for a future transition to a microservice architecture by enabling independent deployment of specific modules.

    Best Practices for Route Organization:

    • Group logically: Group related routes into single files (e.g., all /users routes in a users.ts or users.js file).
    • Use Fastify plugins: Each route file or service should be a Fastify plugin. This ensures encapsulation, allowing each service to have its own independent plugins.
    • Handle large route sets: If a single route file becomes too large, create a sub-folder within routes/ and add an index.ts (or index.js) file. This index file must be a Fastify plugin, and it will be loaded automatically by the application, allowing you to split the logic into multiple files within that folder.
    • Share functionality: To share logic between different routes, place the shared functionality in the plugins folder and expose it using decorators.
  3. Share functionality between routes using plugins and decorators

    main

    When you need to share functionality (such as database connections, authentication logic, or utility functions) across multiple route files, do not define them within the routes/ folder. Instead:

    1. Place the shared functionality in the plugins/ folder.
    2. Register the functionality as a Fastify plugin.
    3. Use decorators to make the functionality available to your routes.
  4. How to use the Plugins folder for cross-cutting concerns

    main

    The plugins folder is used to define behavior that is common to all routes in your application. You should place logic for cross-cutting concerns here, such as:

    • Authentication
    • Caching
    • Template engines
    • Other shared application logic

    Files in this folder are typically wrapped with the fastify-plugin module to make them non-encapsulated. This allows them to define decorators and set hooks that are accessible throughout the rest of your application.

  5. Use the Plugins folder for cross-cutting concerns

    main

    In a fastify-cli application, the plugins folder is intended for defining behavior that is common to all routes. You should place logic for cross-cutting concerns here, such as:

    • Authentication
    • Caching
    • Template engines
    • Other application-wide behaviors

    Files in this folder are typically defined using the fastify-plugin module. Using fastify-plugin makes these plugins non-encapsulated, allowing them to define decorators and set hooks that are accessible throughout the rest of your application.

  6. Enable logging in tests

    main

    By default, log output is consumed by the Node Test runner. If you want log messages to appear in your console during testing, you must configure your logger to output to stderr (destination 2) instead of stdout.

    You can pass this configuration via the serverOptions parameter in the build or listen helpers.

    const { build } = require('fastify-cli/helper')
    const { test } = require('node:test')
    const assert = require('node:assert')
    
    const logger = {
      transport: {
        target: 'pino-pretty',
        options: {
          destination: 2, // Redirects to stderr
        },
      },
    }
    
    const argv = ['app.js']
    
    test('test my application with logging enabled', async t => {
      const app = await build(argv, {}, { logger })
      t.after(() => app.close())
    
      const res = await app.inject('/')
      assert.deepStrictEqual(res.json(), { hello: 'one' })
    })
  7. Scaffold a new plugin project with `generate-plugin`

    main

    Use fastify generate-plugin <yourplugin> to create a boilerplate for plugin development.

    Workflow:

    1. fastify generate-plugin <yourplugin>
    2. cd yourplugin
    3. npm install

    Available Scripts:

    • npm run unit: Runs all unit tests.
    • npm run lint: Checks code style.
    • npm run test:typescript: Runs type tests.
    • npm test: Runs all checks at once.
    $ fastify generate-plugin my-plugin
  8. Start a Fastify server with `fastify start`

    main

    Use fastify start <plugin_file> to launch a Fastify server using a specific plugin file as the entry point. The plugin can be a standard CommonJS module, an async function, or an EcmaScript Module (ESM).

    Plugin Formats

    CommonJS (Node 8+):

    module.exports = function (fastify, options, next) {
      fastify.get('/', function (req, reply) {
        reply.send({ hello: 'world' })
      })
      next()
    }

    Async/Await (Node 8+):

    module.exports = async function (fastify, options) {
      fastify.get('/', async function (req, reply) {
        return { hello: 'world' }
      })
    }

    ESM (Node 14+ or 12.17.0+ < 13.0.0): If using ESM, ensure your package.json has "type": "module" or use the .mjs extension.

    export default async function plugin (fastify, options) {
      fastify.get('/foo/', async function (req, reply) {
        return 'foo'
      })
    }
    
    export const options = {
      ignoreTrailingSlash: true
    }

    Custom Server and Plugin Options

    1. Server Options: To pass custom options to the server creation (e.g., HTTPS settings), export an options object from your plugin file and use the --options flag.

      module.exports.options = {
        https: { key: 'key', cert: 'cert' }
      }

      $ fastify start plugin.js --options

    2. Plugin Options: To pass custom options directly to your plugin, add them after the -- terminator. CLI arguments take precedence over the --options flag. $ fastify start plugin.js -- --one

    $ fastify start plugin.js
  9. Scaffold a new Fastify project with `generate`

    main

    Use fastify generate <yourapp> to create a new project structure.

    Workflow:

    1. fastify generate <yourapp>
    2. cd yourapp
    3. npm install

    Project Structure:

    • app.js: The entry point (a standard Fastify plugin).
    • plugins/: Custom plugins.
    • routes/: Endpoint declarations.
    • test/: Test files.

    Available Flags:

    • --esm: Generates an ESM-based JavaScript template.
    • --lang=ts or --lang=typescript: Uses the TypeScript template.
    • --integrate: Use this if generating into the current directory (.) that already contains a package.json. It will add/alter main, scripts, dependencies, and devDependencies. Use with care as it may overwrite existing files like app.js.
    • --standardlint: Includes the Standard linter for JavaScript templates.
    $ fastify generate my-app
  10. Organize application endpoints in the Routes folder

    main

    The routes/ folder is used to define the endpoints of your web application. Following a modular monolith approach, each route file should be a Fastify plugin. This structure allows you to group related routes logically (e.g., all /users routes in users.js) and facilitates future scaling or extraction into microservices.

    To manage complexity:

    • Logical Grouping: Group routes by resource (e.g., users.js, products.js).
    • Sub-folders: If a single route file becomes too large, create a folder containing an index.js file. This index.js must be a Fastify plugin, and it will be automatically loaded by the application, allowing you to split the routes into multiple files within that folder.