Prismaのmutation deleteを使いたい
Backendでnode.js(ライブラリーはexpress.js),FrontendでReactを使用しています。
Prisma2でGraphQLを操作しています。
現在は下記のようなコードです。
Frontで投稿したポストをボタン押したときに消したいです。
backendのdeleteのところが間違っていると思います。
Frontでボタンを押したときにdata:nullで返ってきてerrorになります。
{errors: [{,…}], data: null}
data: null
errors: [{,…}]
0: {,…}
locations: [{line: 2, column: 3}]
0: {line: 2, column: 3}
column: 3
line: 2
message: "\nInvalid `prisma.user.update()` invocation:\n\n{\n where: {\n id: 1\n },\n data: {\n posts: {\n delete: {\n '0': {\n? id?: Int\n }\n },\n? create?: PostCreateWithoutAuthorInput | PostCreateWithoutAuthorInput[] | PostUncheckedCreateWithoutAuthorInput | PostUncheckedCreateWithoutAuthorInput[],\n? connectOrCreate?: PostCreateOrConnectWithoutAuthorInput | PostCreateOrConnectWithoutAuthorInput[],\n? upsert?: PostUpsertWithWhereUniqueWithoutAuthorInput | PostUpsertWithWhereUniqueWithoutAuthorInput[],\n? createMany?: {\n? data: PostCreateManyAuthorInput,\n? skipDuplicates?: Boolean\n? },\n? connect?: PostWhereUniqueInput | PostWhereUniqueInput[],\n? set?: PostWhereUniqueInput | PostWhereUniqueInput[],\n? disconnect?: PostWhereUniqueInput | PostWhereUniqueInput[],\n? update?: PostUpdateWithWhereUniqueWithoutAuthorInput | PostUpdateWithWhereUniqueWithoutAuthorInput[],\n? updateMany?: PostUpdateManyWithWhereWithoutAuthorInput | PostUpdateManyWithWhereWithoutAuthorInput[],\n? deleteMany?: PostScalarWhereInput | PostScalarWhereInput[]\n }\n }\n}\n\nArgument data.posts.delete of type PostWhereUniqueInput needs at least one argument. Available args are listed in green.\n\nNote: Lines with ? are optional.\n"
path: ["deletePost"]
0: "deletePost"
datamodel post
model Post {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
title String @db.VarChar(255)
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId Int
}
Backend
import express from "express";
import cors from "cors";
import { PrismaClient } from "@prisma/client";
import { graphqlHTTP } from "express-graphql";
import { makeExecutableSchema } from "@graphql-tools/schema";
export interface Context {
prisma: PrismaClient;
}
const prisma = new PrismaClient();
const typeDefs = `
type User {
id:Int!
name: String
email: String!
}
type Post {
id: Int
title: String!
content:String!
}
type Query {
allUsers: [User!]!
allPosts: [Post!]!
}
type Mutation {
createPost(
title: String!
content:String!
):Post!
deletePost(
id: Int
):Post!
createUser(
name: String
email:String!
):User!
}
`;
type argsPostType = {
title: string;
content: string;
};
type argsDeletePostType = {
id: number ;
};
type argsUserType = {
name: string;
email: string;
};
const resolvers = {
Query: {
allUsers: () => {
return prisma.user.findMany();
},
allPosts: () => {
return prisma.post.findMany();
},
},
Mutation: {
createPost: (parent: any, args: argsPostType, context: any, info: any) => {
const newPost = prisma.post.create({
data: {
title: args.title,
content: args.content,
author: {
connect: {
id: 1,
},
},
published: true,
},
});
return newPost;
},
deletePost: (
parent: any,
args: argsDeletePostType,
context: any,
info: any
) => {
const deletedPost = prisma.user.update({
where: {
id: 1,
},
data: {
posts: {
delete: [{ id: args.id }],
},
},
});
return deletedPost;
},
createUser: (parent: any, args: argsUserType, context: any, info: any) => {
const newUser = prisma.user.create({
data: {
name: args.name,
email: args.email,
},
});
return newUser;
},
},
};
export const schema = makeExecutableSchema({
resolvers,
typeDefs,
});
const app = express();
app.use(cors());
app.use(
"/graphql",
graphqlHTTP({
schema,
graphiql: true,
})
);
if (process.env.NODE_ENV !== "production") {
require("dotenv").config();
}
const PORT = process.env.PORT || 3001;
app.listen(PORT, () => {
console.log(`接続完了! ${PORT}.`);
});
Front
import { useQuery, gql, useMutation } from '@apollo/client'
import { Button } from 'antd'
export const USER_DATA = gql`
query allUsers {
allUsers {
id
name
email
}
}
`
export const POST_DATA = gql`
query allPosts {
allPosts {
id
title
content
}
}
`
const DELETE_POST = gql`
mutation deletePost($id: Int) {
deletePost(id: $id) {
id
}
}
`
export const PostsComponent = () => {
const {
data: user_data,
loading: user_loading,
error: user_error,
} = useQuery(USER_DATA)
const {
data: post_data,
loading: post_loading,
error: post_error,
} = useQuery(POST_DATA)
const [deletePost] = useMutation(DELETE_POST, {
refetchQueries: ['allPosts'],
})
const deletePostButton = () => {
deletePost()
alert('削除しました')
}
if (post_loading || user_loading) return <p>Loading...</p>
if (post_error || user_error) return <p>Error...</p>
return (
<div>
<div className="userData">
{user_data.allUsers.length > 0 &&
user_data.allUsers.map(
({
id,
name,
email,
}: {
id: string
name: string
email: string
}) => {
return (
<div key={id}>
<p>名前:{name}</p>
<p>メール:{email}</p>
</div>
)
},
)}
</div>
<div className="postData">
{post_data.allPosts.length > 0 &&
post_data.allPosts.map(
({
id,
title,
content,
}: {
id: number | undefined
title: string
content: string
}) => {
return (
<div key={id}>
<p>タイトル:{title}</p>
<p>内容:{content}</p>
<Button onClick={() => deletePostButton()}>削除</Button>
</div>
)
},
)}
</div>
</div>
)
}