trpc-openapi icon indicating copy to clipboard operation
trpc-openapi copied to clipboard

Example using create-t3

Open 28development opened this issue 1 year ago • 4 comments

Hi, I have some issues settings trpc-openapi on a new t3 application.

So far I added an openapi.ts file:

import { generateOpenApiDocument } from 'trpc-openapi';
import { appRouter } from './root';

export const openApiDocument = generateOpenApiDocument(appRouter, {
    title: 'tRPC OpenAPI - test',
    version: '1.0.0',
    baseUrl: 'http://localhost:3000/api',
});

Here: server/api/openapi.ts

Then I updated my router to include the example route like this:

import { documentRouter } from "@/server/api/routers/document";
import { favoriteRouter } from "@/server/api/routers/favorite";
import { messageRouter } from "@/server/api/routers/message";
import { realEstateRouter } from '@/server/api/routers/real-estate';
import { userActivityRouter } from '@/server/api/routers/user-activity';
import { z } from "zod";
import { router, t } from './trpc';


/**
 * This is the primary router for your server.
 *
 * All routers added in /api/routers should be manually added here.
 */
export const appRouter = router({
  realEstate: realEstateRouter,
  document: documentRouter,
  userActivity: userActivityRouter,
  message: messageRouter,
  favorite: favoriteRouter,
  sayHello: t.procedure
    .meta({ /* 👉 */ openapi: { method: 'GET', path: '/say-hello' } })
    .input(z.object({ name: z.string() }))
    .output(z.object({ greeting: z.string() }))
    .query(({ input }) => {
      return { greeting: `Hello ${input.name}!` };
    }),
});

export type AppRouter = typeof appRouter;

But right now I am confused where to continue and how to actually start it so that I can expose my api.

28development avatar Jul 16 '23 11:07 28development

Hi @28development after it I check the endpoint

const res = await fetch('http://localhost:3000/say-hello?name=James', { method: 'GET' });
const body = await res.json(); /* { greeting: 'Hello James!' } 

I to get sure the endpoint is working fine. If you scroll to examples and check NextJS example they said

// pages/api/[...trpc].ts
import { createOpenApiNextHandler } from 'trpc-openapi';

import { appRouter } from '../../server/appRouter';

export default createOpenApiNextHandler({ router: appRouter });

But we have a different code in this file

import { createNextApiHandler } from "@trpc/server/adapters/next";
import { env } from "@/env.mjs";
import { appRouter } from "@/server/api/root";
import { createTRPCContext } from "@/server/api/trpc";

// export API handler
export default createNextApiHandler({
  router: appRouter,
  createContext: createTRPCContext,
  onError:
    env.NODE_ENV === "development"
      ? ({ path, error }) => {
          console.error(
            `❌ tRPC failed on ${path ?? "<no-path>"}: ${error.message}`
          );
        }
      : undefined,
});

this is the file

import type {
  NextApiHandler,
  NextApiRequest,
  NextApiResponse,
} from 'next/types';
import { AnyRouter } from '../core';
import { TRPCError } from '../error/TRPCError';
import { getErrorShape } from '../shared/getErrorShape';
import {
  NodeHTTPCreateContextFnOptions,
  NodeHTTPHandlerOptions,
  nodeHTTPRequestHandler,
} from './node-http';

export type CreateNextContextOptions = NodeHTTPCreateContextFnOptions<
  NextApiRequest,
  NextApiResponse
>;

export function createNextApiHandler<TRouter extends AnyRouter>(
  opts: NodeHTTPHandlerOptions<TRouter, NextApiRequest, NextApiResponse>,
): NextApiHandler {
  return async (req, res) => {
    function getPath(): string | null {
      if (typeof req.query.trpc === 'string') {
        return req.query.trpc;
      }
      if (Array.isArray(req.query.trpc)) {
        return req.query.trpc.join('/');
      }
      return null;
    }
    const path = getPath();

    if (path === null) {
      const error = getErrorShape({
        config: opts.router._def._config,
        error: new TRPCError({
          message:
            'Query "trpc" not found - is the file named `[trpc]`.ts or `[...trpc].ts`?',
          code: 'INTERNAL_SERVER_ERROR',
        }),
        type: 'unknown',
        ctx: undefined,
        path: undefined,
        input: undefined,
      });
      res.statusCode = 500;
      res.json({
        id: -1,
        error,
      });
      return;
    }

    await nodeHTTPRequestHandler({
      ...opts,
      req,
      res,
      path,
    });
  };
}

But IM stuck on this step If you find some solution just let me know

LongJohnSilver1504 avatar Aug 03 '23 23:08 LongJohnSilver1504

hello, did you solve the mystery ?

Fadlo31 avatar Aug 14 '23 12:08 Fadlo31

just replace createNextApiHandler with createOpenApiNextHandler

omercnet avatar Aug 25 '23 12:08 omercnet

Anyone found a solution?

realmers avatar Mar 02 '24 15:03 realmers