Search code examples
prismaprisma2

is there a better way to make a POST request with Prisma Client?


Trying to make a POST request but got an error That I cannot explain/ resolve on my own. Below are steps to recreate the error:

Schema/model The Template has a list of Creative and Objective, Objective has a description, and the Creative has a few columns - two of which are Strings

model Template {
  id    Int    @id @default(autoincrement())
  title String @unique @default(cuid())

  // Relation fields
  objective       Objective[]
  creative        Creative[]
  createdAt        DateTime           @default(now())
  updatedAt        DateTime           @updatedAt
}

model Objective {
  id          Int      @id @default(autoincrement())
  description String
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt
}

model Creative {
  id              Int      @id @default(autoincrement())
  owner_id        String   @default(cuid())
  campaign_id     String   @default(cuid())
  parent_c_id     String   @default(cuid())
  brandLogo       String
  brandName       String
  createdAt       DateTime @default(now())
  updatedAt       DateTime @updatedAt
}

Here is my Post Route. The description is destructured from the data body, while the brandName and brandLogo are destructured as well from the data body.

//postRoute
router.post("/templates", async (req, res) => {
  const { description } = req.body.data.objective;

  const { brandName, brandLogo} = req.body.data.creative;

  try {
    const template = await prisma.template.create({
      data: {
        objective: {
          create: description
        },
        creative: {
          create: {
            brandName,
            brandLogo,
          }
        }
      },
      include: {
        objective: true,
        creative: true
      }
    });
    res.status(200).json({ data: template, error: "", status: 200 });
  } catch (error) {
    console.log(error);
    res.status(500).json({ data: {}, error: error, status: 500 });
  }
});


Here is the test data I used

{
    "data": {
      "objective":{
          "description": "This is a teesc for obj"
      },
      "creative": {
          "brandName": "This is a test bndname",
          "brandLogo": "www.test333.com/jpg"
      }
  }
}

Finally, here is the error I got (part of it)

{
    query_validation_error: 'Unable to match input value to any allowed input type for the field. Parse errors: [Query parsing/validation error at `Mutation.createOneTemplate.data.TemplateCreateInput.objective.ObjectiveCreateNestedManyWithoutTemplateInput.create`: Unable to match input value to any allowed input type for the field. Parse errors: [Query parsing/validation error at `Mutation.createOneTemplate.data.TemplateCreateInput.objective.ObjectiveCreateNestedManyWithoutTemplateInput.create`: Value types mismatch. Have: List([String("This is a teesc for obj")]), want: Object(ObjectiveCreateWithoutTemplateInput), Query parsing/validation error at `Mutation.createOneTemplate.data.TemplateCreateInput.objective.ObjectiveCreateNestedManyWithoutTemplateInput.create`: Value types mismatch. Have: String("This is a teesc for obj"), want: Object(ObjectiveCreateWithoutTemplateInput), Query parsing/validation error at `Mutation.createOneTemplate.data.TemplateCreateInput.objective.ObjectiveCreateNestedManyWithoutTemplateInput.create`: Value types mismatch. Have: List([String("This is a teesc for obj")]), want: Object(ObjectiveUncheckedCreateWithoutTemplateInput), Query parsing/validation error at `Mutation.createOneTemplate.data.TemplateCreateInput.objective.ObjectiveCreateNestedManyWithoutTemplateInput.create`: Value types mismatch. Have: String("This is a teesc for obj"), want: Object(ObjectiveUncheckedCreateWithoutTemplateInput)], Query parsing/validation error at `Mutation.createOneTemplate.data.TemplateUncheckedCreateInput.objective.ObjectiveUncheckedCreateNestedManyWithoutTemplateInput.create`: Unable to match input value to any allowed input type for the field. Parse errors: [Query parsing/validation error at `Mutation.createOneTemplate.data.TemplateUncheckedCreateInput.objective.ObjectiveUncheckedCreateNestedManyWithoutTemplateInput.create`: Value types mismatch. Have: List([String("This is a teesc for obj")]), want: Object(ObjectiveCreateWithoutTemplateInput), Query parsing/validation error at `Mutation.createOneTemplate.data.TemplateUncheckedCreateInput.objective.ObjectiveUncheckedCreateNestedManyWithoutTemplateInput.create`: Value types mismatch. Have: String("This is a teesc for obj"), want: Object(ObjectiveCreateWithoutTemplateInput), Query parsing/validation error at `Mutation.createOneTemplate.data.TemplateUncheckedCreateInput.objective.ObjectiveUncheckedCreateNestedManyWithoutTemplateInput.create`: Value types mismatch. Have: List([String("This is a teesc for obj")]), want: Object(ObjectiveUncheckedCreateWithoutTemplateInput), Query parsing/validation error at `Mutation.createOneTemplate.data.TemplateUncheckedCreateInput.objective.ObjectiveUncheckedCreateNestedManyWithoutTemplateInput.create`: Value types mismatch. Have: String("This is a teesc for obj"), want: Object(ObjectiveUncheckedCreateWithoutTemplateInput)]]',
    query_position: 'Mutation.createOneTemplate.data'
  }


Solution

  • I have modified your schema as follow:

    datasource mysql {
      provider = "mysql"
      url      = env("DATABASE_URL")
    }
    
    generator client {
      provider = "prisma-client-js"
    }
    
    model Template {
      id    Int    @id @default(autoincrement())
      title String @unique @default(cuid())
    
      // Relation fields
      objectives       Objective[] @relation("objectiveTemplate")
      creatives       Creative[] @relation("creativeTemplate")
      createdAt        DateTime           @default(now())
      updatedAt        DateTime           @updatedAt
    }
    
    model Objective {
      id          Int      @id @default(autoincrement())
      description String
      createdAt   DateTime @default(now())
      updatedAt   DateTime @updatedAt
      template    Template @relation("objectiveTemplate", fields: [templateId], references: [id])
      templateId  Int
    }
    
    model Creative {
      id              Int      @id @default(autoincrement())
      owner_id        String   @default(cuid())
      campaign_id     String   @default(cuid())
      parent_c_id     String   @default(cuid())
      brandLogo       String
      brandName       String
      createdAt       DateTime @default(now())
      updatedAt       DateTime @updatedAt
      template    Template @relation("creativeTemplate",fields: [templateId], references: [id])
      templateId  Int
    }
    

    and I have executed the following:

    const { PrismaClient } = require('@prisma/client')
    const prisma = new PrismaClient()
    
    const saveData = async (data) => {
      const template = await prisma.template.create({
        data: {
          title: 'my template' + Math.random(),
          objectives: {
            create: [
              {
                description: 'my objective',
              },
            ],
          },
          creatives: {
            create: [
              {
                brandLogo: 'id',
                brandName: 'id',
              },
            ],
          },
        },
      })
    
      console.log(JSON.stringify(await prisma.template.findMany({ include: { objectives: true, creatives: true } }), null, 2));
    }
    
    saveData()
    

    and all works properly

    enter image description here