🌸 GraphQL

[Prisma Client] null and undefined

ji-hyun 2022. 5. 10. 15:08

null 과 undefined 차이점

nullvalue(= 값) 이다.

undefined"do nothing" 을 의미한다.

 

 

 

 

 

 

다음 예에서 emailInput 이 null 이면, email 필드를 undefined 로 해보자. (= do nothing 하라는 뜻)

 

const update = await prisma.user.update({
  where: {
    id: 1,
  },
  data: {
    name: "Petunia",
    email: emailInput != null ? emailInput : undefined, // If null, don't include in update!
  },
});

function getEmail() {
  const random = Math.floor(Math.random() * 10);

  if (random > 5) {
    return "ariadne@prisma.io"; // Could be null!
  }

  return null;
}

 

이것은 아래와 동일한 의미.

 

 

const update = await prisma.user.update({
  where: {
    id: 1,
  },
  data: {
    name: "Petunia",
    // No email update here...
  },
});

function getEmail() {
  const random = Math.floor(Math.random() * 10);

  if (random > 5) {
    return "ariadne@prisma.io"; // Could be null!
  }

  return null;
}

 

 

 

 

 

 

반면, email 필드를 null 로 설정하면 동작하지 않습니다. (= 에러)

 

email: isValid(emailInput) ? emailInput : null, // email is a mandatory field!

 

 

 

 

 

 

 

사용 사례 : GraphQL resolver 에서 null, undefined

 

참고 스키마

 

model User {
  email String  @unique
  id    Int     @id @default(autoincrement())
  name  String?
  posts Post[]
}

model Post {
  id       String @id @default(cuid())
  title    String
  authorId Int?
  views    Int?
  author   User?  @relation(fields: [authorId], references: [id])
}

 

 

다음 예제는 User 를 업데이트하는 mutation 을 알아보자.

(세부사항: author 의 email 이나 name 로 업데이트 할 것)

 

type Mutation {
  // Update author's email or name, or both - or neither!
  updateUser(id: Int!, authorEmail: String, authorName: String): User!
}

 

 

 

그러나 만약 authorEmail, authorName 필드에 null 을 보내면 다음과 같은 일이 일어난다.

 

  • args.authorEmail 이 null 이면, 에러
  • args.authorName 이 null 이면, 원하는 대로 동작하지 않을 가능성이 큼

 

 

 

 

 

대신에 email 이나 name 의 inputValue 가 null 이면, undefined 로 세팅하여 아무 일도 일어나지 않게( = do nothing ) 시켜보자.

 

updateUser: (parent, args, ctx: Context) => {
  return ctx.prisma.user.update({
    where: { id: Number(args.id) },
    data: {
|      email: args.authorEmail != null ? args.authorEmail : undefined, // If null, do nothing
|      name: args.authorName != null ? args.authorName : undefined // If null, do nothing
    },
  })
},

 

 

 

 

 

 

참고해보면 좋은 글

 

Thanks for the question! In the Prisma Client there's a specific difference between null and undefined.

null is a specific value that's persisted in an SQL database as NULL.

If I run:

 

prisma.user.create({ 
  data: {
    id: 10,
    customer: null
  }
}

 

The row in an SQL database looks like this:

 

< id, customer >

10 NULL

 

 

 

 

 

undefined is the absence of any value. That looks like this:

 

prisma.user.create({ 
  data: {
    id: 10,
    customer: undefined
  }
}

 

 

Conceptually that's the same as

 

prisma.user.create({ 
  data: {
    id: 10
  }
}

 

 

This leaves the prisma engine to decide the value, falling back on the @default value.

< id, customer >

10 'default value'

 

 

 

 

 

 

 

★ 조건부에서의 null 과 undefined

예상치 못한 결과를 생성할 수 있는 조건부 필터링에 대한 몇 가지 주의 사항이 있습니다.

 

 

필터 조건이 0 일때 를 보면 OR 연산자는 빈 list 를 반환하고, AND, NOT 연산자는 모든 items 들을 반환한다.

이게 무슨 뜻인지 다음 예제를 통해 알아보자.

 

 

 

interface FormData {
  name: string
  email?: string
}

const formData: FormData = {
  name: 'Emelie',
}

const users = await prisma.user.findMany({
  where: {
    OR: [
      {
        email: {
          contains: formData.email,
        },
      },
    ],
  },
})

// returns: []

 

 

interface FormData {
  name: string
  email?: string
}

const formData: FormData = {
  name: 'Emelie',
}

const users = await prisma.user.findMany({
  where: {
    AND: [
      {
        email: {
          contains: formData.email,
        },
      },
    ],
  },
})

// returns: { id: 1, email: 'ems@boop.com', name: 'Emelie' }

const users = await prisma.user.findMany({
  where: {
    NOT: [
      {
        email: {
          contains: formData.email,
        },
      },
    ],
  },
})

// returns: { id: 1, email: 'ems@boop.com', name: 'Emelie' }

 

 

이것은 And, Not 연산자에 undefined 를 전달하는데 아무것도 전달하지 않는 것과 같다.

이 예제에서의 findMany 쿼리는 어떤 필터도 없고 모든 user 를 반환한다.

 

 

 

 

 

 

 

 

진짜 그렇게 나오는지 궁금해서 확인해보았다.

 

 

 

 

OR, AND 연산자에 따라 결과가 다르다.