fastify-api

0.2.0 • Public • Published

fastify-api

A radically simple API routing and method injection plugin for Fastify.

Uses fastify.inject under the hood, with developer ergonomics in mind.

Injects fastify.api with automatically mapped methods from route definitions.

Usage

  1. Original fastify.{method}() with exposeAs option, without params:
fastify.get('/1/method', { exposeAs: 'method' }, (_, reply) => {
  reply.send('Hello from /1/method')
})
fastify.get('/invoke/1/method', async (_, reply) => {
  try {
    const result = await fastify.api.client.method()
    reply.send(result)
  } catch (err) {
    console.error(err)
  }
})
  1. Original fastify.() with exposeAs option, with params:
fastify.get('/2/method/:id', { exposeAs: 'methodWithParams' }, ({ id }, _, reply) => {
  reply.send(`Hello from /2/method/ with id ${id}`)
})
fastify.get('/invoke/2/method', async (req, reply) => {
  const result = await fastify.api.client.methodWithParams({ id: 123 })
  reply.send(result)
})
  1. Will automatically create a nested structure too, if needed:
fastify.get('/3/nested/method/:id', { exposeAs: 'nested.method' }, ({ id }, _, reply) => {
  reply.send(`Hello from /3/nested/method/ with id ${id}`)
})
fastify.get('/invoke/3/nested/method', async (req, reply) => {
  const result = await fastify.api.client.nested.method({ id: 123 })
  reply.send(result)
})
  1. Modified fastify.api.() setter if the handler is a named function:
fastify.api.get('/4/method', function methodFromNamedFunction ({ id }, _, reply) {
  reply.send(`Hello from /4/method with id ${id}`)
})
fastify.get('/invoke/4/method', async (req, reply) => {
  const result = await fastify.api.client.methodFromNamedFunction({ id: 123 })
  reply.send(result)
})
  1. Modified fastify.api(setter) helper to quickly define multiple methods:

Makes more sense if the setter function is coming from another file.

fastify.api(({ get }) => ({
  topLevelMethod: get('/5/top-level-method/:id', function ({ id }, _, reply) {
    reply.send({ id })
  }),
  nestedMethods: {
    method: get('/5/nested-methods/method/:id', ({ id }, _, reply) => {
      reply.send({ id })
    }),
    otherMethod: get('/5/nested-methods/other-method/:id', ({ id }, _, reply) => {
      reply.send({ id })
    }),
    deeplyNestedMethods: {
      method: get('/5/nested-methods/deeply-nested-methods/method/:id', ({ id }, _, reply) => {
        reply.send({ id })
      }),
      otherMethod: get('/5/nested-methods/deeply-nested-methods/other-method/:id', ({ id }, _, reply) => {
        reply.send({ id })
      })
    }
  }
}))

fastify.get('/invoke/5/top-level-method', async (req, reply) => {
  const result = await fastify.api.client.topLevelMethod({ id: 123 })
  reply.send(result)
})
fastify.get('/invoke/5/nested-methods/method', async (_, reply) => {
  const result = await fastify.api.client.nestedMethods.method({ id: 123 })
  reply.send(result)
})
fastify.get('/invoke/5/nested-methods/other-method', async (_, reply) => {
  const result = await fastify.api.client.nestedMethods.otherMethod({ id: 123 })
  reply.send(result)
})
fastify.get('/invoke/5/nested-methods/deeply-nested-methods/method', async (_, reply) => {
  const result = await fastify.api.client.nestedMethods.deeplyNestedMethods.method({ id: 123 })
  reply.send(result)
})
fastify.get('/invoke/5/nested-methods/deeply-nested-methods/other-method', async (_, reply) => {
  const result = await fastify.api.client.nestedMethods.deeplyNestedMethods.otherMethod({ id: 123 })
  reply.send(result)
})
  1. Any API method exposed in fastify.api.client can take options:
fastify.get('/6/method', { exposeAs: 'methodWithOptions' }, (req, reply) => {
  reply.send(`Hello from /6/method/ with query.arg ${
    req.query.arg
  } and the x-foobar header ${
    req.headers['x-foobar']
  }`)
})
fastify.get('/invoke/6/method', async (_, reply) => {
  const result = await fastify.api.client.methodWithOptions({
    query: {
      arg: 1
    },
    headers: {
      'x-foobar': 1
    }
  })
  reply.send(result)
})

API responses

If you call a route via HTTP, it'll operate normally as if weren't using the plugin. If you use fastify.api.client.xyz() to invoke it from another handler, you'll get an object containing { json, body, status, headers } as response. If it's unable to parse a JSON document out of body, json is undefined.

/fastify-api/

    Package Sidebar

    Install

    npm i fastify-api

    Weekly Downloads

    37

    Version

    0.2.0

    License

    MIT

    Unpacked Size

    10.5 kB

    Total Files

    3

    Last publish

    Collaborators

    • galvez