Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Add "examples" to OpenAPI schema #261

Closed
rhinodavid opened this issue Feb 21, 2023 · 6 comments
Closed

RFC: Add "examples" to OpenAPI schema #261

rhinodavid opened this issue Feb 21, 2023 · 6 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@rhinodavid
Copy link

I'm looking for a way to add openapi annotations to inputs and outputs.. something like:

// Router
export const appRouter = t.router({
  sayHello: t.procedure
    .meta({ openapi: { method: 'GET', path: '/say-hello/{name}' } })
    .input(z.object({ name: z.string().openapi({ description: "Your full name", example: "Sonny Moore" }) /* 👈 */, greeting: z.string() }))
    .output(z.object({ greeting: z.string() }))
    .query(({ input }) => {
      return { greeting: `${input.greeting} ${input.name}!` };
    });
});

The zod-to-openapi extension enables the openapi annotation, but you have to then manually create each path.

What would great is a mashup of trpc-openapi and zod-to-openapi.

I think this would be possible by swapping out the zod-to-json-schema library with the generator in zod-to-openapi.

If there's interest in this I might be able to spend some time on it.

@jlalmes
Copy link
Owner

jlalmes commented Feb 24, 2023

It is already possible to provide a description to a field using .describe(string) eg.

- .input(z.object({ name: z.string().openapi({ description: "Your full name", example: "Sonny Moore" }) /* 👈 */, greeting: z.string() }))
+ .input(z.object({ name: z.string().describe('Your full name') /* 👈 */, greeting: z.string() }))

As you are not the first one to ask for this feature, I think we should add an examples property to OpenApiMeta object so that we can generate "examples" schemas in the OpenAPI document.

.meta({ 
  openapi: { 
    method: 'GET', 
    path: '/say-hello/{name}',
    // 👇 Any thoughts on this API? 
    examples: {
      input: [{ name: 'Sonny Moore', greeting: 'Hello' }],
      output: [{ greeting: 'Hello Sonny Moore!' }]
    }
  } 
})

PS. one of my fave songs of all time 👉 https://www.youtube.com/watch?v=AM3J4428cyc

@jlalmes jlalmes added the enhancement New feature or request label Feb 24, 2023
@jlalmes jlalmes changed the title Annotate request and response with openapi data RFC: Add "examples" to OpenAPI schema Feb 24, 2023
@tcaputi
Copy link

tcaputi commented Feb 25, 2023

I literally was about to file this as an issue. And the propsed api was pretty close to what i was going to suggest. The documentation that came out of this project was very nice and required very little effort from me, but this is what the swagger editor does when it tried to generate an example for one of my routes. The logoUrl and thumbnailUrl are the result of using a regex validator:

image

@rhinodavid
Copy link
Author

Somebody finally got one of my skrill references!

Instead of doing just the example what if we allowed the BaseParameterObject to be specified?

Maybe

.meta({ 
  openapi: { 
    method: 'GET', 
    path: '/say-hello/{name}',
    inputMeta: 
      [{ name: { examples: ["eric", "stan" }, greeting: { deprecated: true }],
    outputMeta: [{ greeting: { example: "hidey ho" } }]
    }
  } 
})

I guess certain fields of BaseParameterObject would collide (description for example), so maybe just allow a subset?

@tcaputi
Copy link

tcaputi commented Mar 3, 2023

Any update on when this might happen? I'd love to be able to use this instead of patching the json object i get back from the call.

@emdede
Copy link

emdede commented Apr 13, 2023

+1 implemented trpc-openapi in our project today and this is what is displayed as default example values for some of our RegExes
image

@jlalmes jlalmes added the help wanted Extra attention is needed label May 24, 2023
@jlalmes
Copy link
Owner

jlalmes commented May 24, 2023

This is now supported!

const appRouter = t.router({
  queryExample: t.procedure
    .meta({
      openapi: {
        method: 'GET',
        path: '/query-example/{name}',
        example: {
          request: { name: 'James', greeting: 'Hello' },
          response: { output: 'Hello James' },
        },
      },
    })
    .input(z.object({ name: z.string(), greeting: z.string() }))
    .output(z.object({ output: z.string() }))
    .query(({ input }) => ({
      output: `${input.greeting} ${input.name}`,
    })),

@jlalmes jlalmes closed this as completed May 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

4 participants