次のセットアッププロジェクト.JS , prisma , trpc , nextauth
11848 ワード
背景
最近、私は小さなプロジェクトに取り組んでいました.そこではあまり使われていない技術を使って、それをすべて実践することができました.目的はクローンを作ることでしたKubool これは匿名メッセージを送信できるプラットフォームです.それで始めました.
最初のスタックの選択は以下の通りです.
設定手順
プロジェクトのセットアップでは、上記の技術を使用します.必要条件:
ステップ1:作成&クローンレポスターターテンプレートから
私は、上記の技術でプロジェクトを構築することに関心を集中するようになったので、私は前進し、新しいプロジェクトを開始するたびに自分のためのスターターテンプレートを作成しました.それで、そのスターターテンプレートの上に構築しましょう.
スターターテンプレートへのリンクhttps://github.com/JohannesMogashoa/nextjs-prisma
作成し、ローカルマシンにレポをクローニングした後.コマンドラインツールでそのプロジェクトを開くことができます.実行して依存関係をインストールします
npm install
or yarn install
ステップ2 :プロジェクトにTRPCを追加する
公式TRPCサイトには、以下のようにします.https://trpc.io/ ドキュメントを見てみましょう.
この時点で、コマンドラインツールまたはVSコードの統合ターミナルを使用できます.
yarn add @trpc/client @trpc/server @trpc/react @trpc/next zod react-query superjson ws
次の手順backend
プロジェクトのルートのフォルダutils
and routers
フォルダ内のbackend
フォルダrouters
フォルダを作成するindex.ts
ファイルutils
フォルダクリエイトcontext.ts
and createRouter.ts
ファイルlib
フォルダを作成trpc.ts
ファイルtrp
フォルダの内部pages/api/
, 次に、[trpc].ts
ファイル.- backend/routers/index.ts
- backend/utils/context.ts
- backend/utils/createRouter.ts
- lib/trpc.ts
- pages/api/trpc/[trpc].ts
ステップ3 -バックエンドフォルダを設定する
バックエンド/utils/context
アプリはPrismaとNextauthを使用しているので、これらの“値”を通して簡単にアクセシビリティのコンテキストを使用してTrpcルートの残りの部分を通過することができます.
import { getSession } from "next-auth/react";
import * as trpc from '@trpc/server';
import * as trpcNext from '@trpc/server/adapters/next';
import { NodeHTTPCreateContextFnOptions } from '@trpc/server/adapters/node-http';
import { IncomingMessage } from 'http';
import ws from 'ws';
import {prisma} from "@/lib/prisma"
上記のインポート文をcontext.ts
次にファイルの下のセクションをコピーします.export const createContext = async ({
req,
res,
}:
| trpcNext.CreateNextContextOptions
| NodeHTTPCreateContextFnOptions<IncomingMessage, ws>) => {
const session = await getSession({ req });
return {
req,
res,
prisma,
session,
};
};
export type Context = trpc.inferAsyncReturnType<typeof createContext>;
バックエンド/utils下のコードを
createRouter.ts
ファイルimport { Context } from "./context";
import * as trpc from "@trpc/server";
export function createRouter() {
return trpc.router<Context>()
}
バックエンド/ルーター/インデックスこのファイルでは、TRPCアプリのルータを使用したいと思うすべての異なるルートで作成されます.以下の例は、すべてのルートを同じファイルにしたい場合です.
import { createRouter } from '@/backend/utils/createRouter';
import superjson from "superjson"
import { z } from 'zod';
export const appRouter = createRouter()
.transformer(superjson)
.mutation('set-username', {
input: z.object({
username: z.string(),
email: z.string().email()
}),
async resolve({ ctx, input }) {
await ctx.prisma!.user.update({
where: {
email: input.email,
},
data: {
slug: input.username,
},
})
return { success: true, message: "Username set successfully" }
}
})
.query('get-user', {
input: z.object({
email: z.string().email()
}),
async resolve({ ctx, input }) {
const user = await ctx.prisma!.user.findUnique({
where: {
email: input.email,
},
})
return { success: true, user }
}
})
// export type definition of API
export type AppRouter = typeof appRouter;
あなたが想像できるように、他のルートとそれらのそれぞれのロジックを追加すると、上記のコードはますます大きくなります.それで、より良い方法は別のファイルでルートと場所をグループ化することになっていて、それらのルートを承認に輸入するでしょう.別のファイルを作成するuserRoutes.ts
インサイドbackend/routers
フォルダ.リファクタリングされたコードは以下のような性質を持つでしょう.// backend/routers/index.ts
import { createRouter } from '@/backend/utils/createRouter';
import superjson from "superjson"
import { userRouter } from './userRouter';
export const appRouter = createRouter()
.transformer(superjson)
.merge('user', userRouter)
// other merged routes here
// export type definition of API
export type AppRouter = typeof appRouter;
// backend/routers/userRouter.ts
import { z } from "zod"
import { createRouter } from "../utils/createRouter"
export const userRouter = createRouter()
.mutation('set-username', {
input: z.object({
username: z.string(),
email: z.string().email()
}),
async resolve({ ctx, input }) {
await ctx.prisma!.user.update({
where: {
email: input.email,
},
data: {
slug: input.username,
},
})
return { success: true, message: "Username set successfully" }
}
})
.query('get-user', {
input: z.object({
email: z.string().email()
}),
async resolve({ ctx, input }) {
const user = await ctx.prisma!.user.findUnique({
where: {
email: input.email,
},
})
return { success: true, user }
}
})
すべての上記のコードを追加すると、一時的にbackend/
フォルダとは、他のフォルダ内の他のファイルに移動することができます.lib/trpc.TS
import { AppRouter } from '@/backend/routers';
import { createReactQueryHooks } from '@trpc/react';
export const trpc = createReactQueryHooks<AppRouter>();
ページ/API/trpc/[ trpc ].TSこの部分は、アプリケーションルータで定義されたルータになされた要求を処理するTRPC APIエンドポイントの公式設定です.
import { appRouter, AppRouter } from '@/backend/routers';
import { inferProcedureOutput } from '@trpc/server';
import * as trpcNext from '@trpc/server/adapters/next';
import { createContext } from '@/backend/utils/context';
// export API handler
export default trpcNext.createNextApiHandler({
router: appRouter,
createContext,
onError({ error }) {
if (error.code === 'INTERNAL_SERVER_ERROR') {
// send to bug reporting
console.error('Something went wrong', error);
}
},
});
export type inferQueryResponse<
TRouteKey extends keyof AppRouter["_def"]["queries"]
> = inferProcedureOutput<AppRouter["_def"]["queries"][TRouteKey]>;
この時点で、作成したすべてのファイルに必要なコードを追加して完了しました.現在、TRPCの最終的な実装に移動しますpages/_app.tsx
ファイル.ステップ4 -ページを編集/アプリ。TSXファイル
移動する
pages/_app.tsx
ファイルを作成し、次のように変更します.export default MyApp
次のコードをペーストします// Initializing TRPC server on the Next.js server
import { withTRPC } from "@trpc/next";
import type { AppRouter } from "@/backend/routers";
// Check to see the current environment then generate the appropriate URL
function getBaseUrl() {
if (process.browser) return ""; // Browser should use current path
if (process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}`; // SSR should use vercel url
return `http://localhost:${process.env.PORT ?? 3000}`; // dev SSR should use localhost
}
export default withTRPC<AppRouter>({
config({ ctx }) {
/**
* If you want to use SSR, you need to use the server's full URL
* @link https://trpc.io/docs/ssr
*/
const url = `${getBaseUrl()}/api/trpc`;
return {
url,
/**
* @link https://react-query.tanstack.com/reference/QueryClient
*/
// queryClientConfig: { defaultOptions: { queries: { staleTime: 60 } } },
};
},
/**
* @link https://trpc.io/docs/ssr
*/
ssr: false,
})(MyApp);
Phew!!!それはたくさんのコードでした.この時点で、「フロントエンド」を「バックエンド」に接続する必要がありますutils/trpc.ts
ファイル.ステップ5 - trpcを使う
すべてがバックエンドで実装されているので、クライアントのインスタンスを使用してどこでも使用できるようになりました.FREEの下でResponse Queryを使用しているTRPCのフックを使用して、データベースからユーザを得てみましょう.
import { trpc } from "@/utils/trpc";
import { useSession } from "next-auth/react";
import React from "react";
const UserComponent: React.FC = () => {
const {data: session} = useSession()
const {data} = trpc.useQuery(["get-user", { email: session?.user?.email as string}]);
return (
<div>
<h1>{data?.user?.name}</h1>
<p>{data?.user?.email}</p>
</div>
);
};
export default UserComponent;
この時点で、あなたはあなたのNextJSアプリケーションにTRPCを実装していると幸福に言うことができます.アウトロ
私を信じていないかどうか、私は書かれていたと次の組み込みのAPIルーティングとハンドリングシステムを使用してアプリケーションを完了したが、コードは混乱していた、すべての場所でのタイピングは、バックエンドとクライアント間のエンドツーエンド型の安全性のいくつかの並べ替えを模倣するために.私はTRPCは本当に便利なツールであることを発見し、より頻繁にそれを使用することを楽しみにしています.あなたがNextauthなしでtrpcを使用するgithubレポをチェックアウトしたいならば、見てくださいRoundest by Theo Browne
便利なリンク
Reference
この問題について(次のセットアッププロジェクト.JS , prisma , trpc , nextauth), 我々は、より多くの情報をここで見つけました https://dev.to/johannesmogashoa/setup-project-with-nextjs-prisma-trpc-nextauth-4df1テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol