seriousme / fastify-openapi-glue

A plugin for the Fastify webserver to autogenerate a Fastify configuration based on a OpenApi(v2/v3) specification.
MIT License
196 stars 33 forks source link

`opts` ignored in default template? #589

Open carsten-cc opened 3 weeks ago

carsten-cc commented 3 weeks ago

Hi, in the default template the passed opts parameter seems to be ignored: https://github.com/seriousme/fastify-openapi-glue/blob/529975adf265f7ab5bc342c7624a52db55bd2a68/lib/templates/js/index.js#L13 https://github.com/seriousme/fastify-openapi-glue/blob/529975adf265f7ab5bc342c7624a52db55bd2a68/lib/templates/js/index.js#L14

I'd expect something like fastify.register(openapiGlue, {...pluginOptions, ...opts}); there - or did I miss something?

seriousme commented 3 weeks ago

Hi,

thanks for asking. I checked the fastify documentation, it mentions:

Note: Those options will be ignored when used with fastify-plugin

https://fastify.dev/docs/latest/Reference/Plugins/

Fastify-openapi-glue is using fastify-plugin so I assumed that passing the opts does not do anything.

Do you have an example that currently fails? Did you try fixing the generated code by hand?

Kind regards, Hans

carsten-cc commented 3 weeks ago

Did you try fixing the generated code by hand?

Yes, if I monkey-patch the index.js with the line I gave in my previous comment, it uses my {serviceHandlers: new MyService()} option successfully. Without it, it is ignored.


Do you have an example that currently fails?

Full example

`openapi.yaml`: ```yaml openapi: "3.0.3" tags: - name: debugging description: Routes for debugging info: contact: name: "Placeholder" url: https://example.com title: Example version: 1.0.0 description: >- Example servers: - url: http://localhost:8082 paths: /ping: get: operationId: Ping description: Returns "pong" tags: ["debugging"] responses: "200": description: OK, content: "plain/text": example: "pong" schema: type: string ``` `package.json`: ```json { "name": "fastify-issue", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "generate-api-glue": "openapi-glue -b ./ ./openapi.yaml", "run": "bun run index.js" }, "keywords": [], "author": "", "license": "MIT", "dependencies": { "@fastify/express": "^3.0.0", "bun": "^1.1.13", "fastify": "^4.28.0", "fastify-cli": "^6.2.1", "fastify-openapi-glue": "^4.6.0", "fastify-plugin": "^4.5.1" } } ```

./index.js:

import express from "@fastify/express";
import fastify from "fastify";
import { default as registerAPIPlugin } from "./generated-javascript-project/index.js";

class MyService {
  async Ping(req, reply) {
    console.log("Custom implementation using typescript/zod etc.");
    return "pong";
  }
}

async function start() {
  const server = await fastify();
  await server.register(express);

  await registerAPIPlugin(server, {
    serviceHandlers: new MyService(),
  });

  server.listen({ port: 8082, host: "127.0.0.1" }, (err, address) => {
    console.log(`Server listening at ${address}`);
  });
}
void start();

./generated-javascript-project/index.js

...
export default async function (fastify, opts) {
-  fastify.register(openapiGlue, pluginOptions);
+  fastify.register(openapiGlue, { ...pluginOptions, ...opts }); 
}
...

Without the change the route responds with Ping {} instead of the expected pong.

seriousme commented 3 weeks ago

Hi,

thanks for the explanation. Your usage surprised me a bit as I would have thought that the generated index.js adds little value if you import it again and then want to change the parameters again.

E.g.:

import express from "@fastify/express";
import fastify from "fastify";
import openapiGlue from "fastify-openapi-glue";
import { Security } from "./security.js";

class MyService {
  async Ping(req, reply) {
    console.log("Custom implementation using typescript/zod etc.");
    return "pong";
  }
}

async function start() {
  const server = await fastify();
  await server.register(express);

  await server.register(openapiGlue, {
    specification: "./openapi.yml",
    serviceHandlers: new MyService(),
    securityHandlers: new Security(),
  });

  server.listen({ port: 8082, host: "127.0.0.1" }, (err, address) => {
    console.log(`Server listening at ${address}`);
  });
}
void start();

Would achieve the same effect while ignoring the generated index.js.

However since your case might be useful to others as well I'll patch the template.

Kind regards, Hans

seriousme commented 3 weeks ago

FYI: released as 4.6.1

carsten-cc commented 3 weeks ago

Thanks for patching :).

Would achieve the same effect while ignoring the generated index.js.

True, I assumed some additional logic where I just realized there is none. But at least the unused parameter is now used :).