Project
Graphql Query, prisma
프도의길
2023. 8. 22. 21:39
저번에 구글 로그인을 만들었다 프론트에서 보여준 정보를 백엔드 서버로 보낼 것 이다.
src/graphql/operations/user.ts
import { gql } from "@apollo/client";
export default {
Queries: {
searchUsers: gql`
query SearchUsers($username: String!) {
searchUsers(username: $username) {
id
username
}
}
`,
},
Mutations: {
},
};
쿼리 grapql 만들어준 다음에 Auth.tsx에서 해줍니다.
import { CreateUsernameData, CreateUsernameVariables } from "@/util/types";
import { useMutation } from "@apollo/client";
import { Button, Center, Image, Input, Stack, Text } from "@chakra-ui/react";
import { Session } from "next-auth";
import { signIn } from "next-auth/react";
import { useState } from "react";
import toast from "react-hot-toast";
import UserOperations from "../../graphql/operations/user";
interface IAuthProps {
session: Session | null;
reloadSession: () => void;
}
const Auth = ({ session, reloadSession }: IAuthProps) => {
const [username, setUsername] = useState("");
const [createUsername, { loading, error }] = useMutation<
CreateUsernameData,
CreateUsernameVariables
>(UserOperations.Mutations.createUsername);
const onSubmit = async () => {
if (!username) return;
try {
const { data } = await createUsername({ variables: { username } });
if (!data?.createUsername) {
throw new Error();
}
if (data.createUsername.error) {
const {
createUsername: { error },
} = data;
throw new Error(error);
}
toast.success("Username Successfully");
reloadSession();
} catch (error: any) {
toast.error(error?.message);
console.log("err", error);
}
};
console.log("se", session);
return (
<Center height="100vh">
<Stack spacing={8} align="center">
{session ? (
<>
<Text fontSize="3xl">Creat a Username</Text>
<Input
placeholder="Enter a username"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
<Button width="100%" onClick={onSubmit} isLoading={loading}>
Save
</Button>
</>
) : (
<>
<Text fontSize="3xl">MessengerQL</Text>
<Button
onClick={() => signIn("google")}
leftIcon={<Image height="20px" src="/images/googlelogo.png" />}
>
Continue with Google
</Button>
</>
)}
</Stack>
</Center>
);
};
export default Auth;
백에드 로 가서 먼저 prisma설치를 해줍니다 npm i @prisma/client
밑에 주소는 prisma 세팅 설명입니다.
https://happy8131.tistory.com/116
//backend src/prisma/schema.prisma
generator client {
provider = "prisma-client-js"
binaryTargets = ["native","darwin","darwin-arm64","debian-openssl-1.1.x"]
}
datasource db {
provider = "mongodb"
url = env("MONGODB_URL")
}
model Account {
id String @id @default(auto()) @map("_id") @db.ObjectId
userId String
type String
provider String
providerAccountId String
refresh_token String? @db.String
access_token String? @db.String
expires_at Int?
token_type String?
scope String?
id_token String? @db.String
session_state String?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([provider, providerAccountId])
}
model Session {
id String @id @default(auto()) @map("_id") @db.ObjectId
sessionToken String @unique
userId String
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model User {
id String @id @default(auto()) @map("_id") @db.ObjectId
name String?
email String? @unique
username String? @unique
emailVerified DateTime?
image String?
accounts Account[]
sessions Session[]
}
model VerificationToken {
id String @id @default(auto()) @map("_id") @db.ObjectId
identifier String
token String @unique
expires DateTime
@@unique([identifier, token])
}
//backend src/index.ts
import { ApolloServer } from "apollo-server-express";
import {
ApolloServerPluginDrainHttpServer,
ApolloServerPluginLandingPageLocalDefault,
} from "apollo-server-core";
import { makeExecutableSchema } from "@graphql-tools/schema";
import express from "express";
import http from "http";
import typeDefs from "./graphql/typeDefs";
import resolvers from "./graphql/resolvers";
import { getSession } from "next-auth/react";
import { GraphQLContext, Session } from "./util/types";
import * as dotenv from "dotenv";
import { PrismaClient } from "@prisma/client";
async function main() {
dotenv.config();
const app = express();
const httpServer = http.createServer(app);
const schema = makeExecutableSchema({
typeDefs,
resolvers,
});
const corsOptions = {
origin: process.env.CLIENT_ORIGIN,
credentials: true,
};
const prisma = new PrismaClient();
const server = new ApolloServer({
schema,
csrfPrevention: true,
cache: "bounded",
context: async ({ req, res }): Promise<GraphQLContext> => {
const session = (await getSession({ req })) as Session;
return { session, prisma };
},
plugins: [
ApolloServerPluginDrainHttpServer({ httpServer }),
ApolloServerPluginLandingPageLocalDefault({ embed: true }),
],
});
await server.start();
server.applyMiddleware({ app, cors: corsOptions });
await new Promise<void>((resolve) =>
httpServer.listen({ port: 4000 }, resolve)
);
console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`);
}
main().catch((err) => console.log(err));
prisma를 넣어줍니다.
그리고 다음에 제가 만든 prisma를 npx prisma generate --schema=src/prisma/schema.prisma 적용시켜줍니다.
schema.prisma 데이터가 추가나 수정될때 적용시켜주면됩니다.
백엔드 코드
//backend src/graphql/resolvers/user.ts
import { User } from "@prisma/client";
import { GraphQLError } from "graphql";
import { CreateUsernameResponse, GraphQLContext } from "../../util/types";
const resolvers = {
Query: {
searchUsers: async (
_: any,
args: { username: string },
context: GraphQLContext
): Promise<Array<User>> => {
const { username: searchedUsername } = args;
const { prisma, session } = context;
if (!session?.user) {
throw new GraphQLError("Not authorized");
}
const {
user: { username: myUsername },
} = session;
try {
const users = await prisma.user.findMany({
where: {
username: searchedUsername,
},
});
return users;
} catch (error: any) {
console.log("error", error);
throw new GraphQLError(error?.message);
}
},
},
Mutation: {
},
};
export default resolvers;
그리고 로그인 하면
로그인이 된다
그리고 프론트에서도 prisma를 npx prisma generate --schema=src/prisma/schema.prisma 적용시켜줘야한다