PrismaがCRUD操作を生成することで節約できる何時間ものうんざりする作業に加えて、さらに時間を節約し、データ構造をより高度に制御できる他のいくつかの機能にアクセスできるようになります。 この記事では、スキーマで使用する最も一般的なディレクティブのいくつかについて説明します。

前提条件

スキーマを強化するのに役立つことを行う予定だったので、基本ここを更新できます。

また、選択したデータベースを使用した基本的なPrismaコンテナのセットアップも必要になります。 この記事をチェックアウトするか、DockerでPrismaをセットアップするか、このrepoをコピーして新しいコンテナーにデプロイすることができます。

独自の指令

アプリがあり、同じメールアドレスのユーザーからアプリを保護しながら、新しいユーザーを追加したいとします。 Prismaは、データベースに何かを保存する前に、手動でクエリを送信して一致するものがすでに存在するかどうかを確認する代わりに、それを処理する便利な@uniqueディレクティブを提供します。 IDには、@idと呼ばれる独自の特別な同等物があり、基本的に同じことを行います。

type User {
  id: ID! @id
  name: String!
  email: String! @unique 
  age: Int!
}

これにより、ミューテーションが失敗したときに使用できなかったことをユーザーに通知する条件を設定できます。

デフォルトのディレクティブ

多くの場合、基本ユーザーであるか管理者であるかなど、ユーザーにアカウントに必要なすべての情報を入力させたくないことは明らかです。 これらのタイプのデータにデフォルト値を追加できると非常に便利です。

@defaultディレクティブを使用してプレースホルダー値を追加するのが、最も簡単な処理方法です。

type User {
  id: ID! @id
  name: String!
  email: String! @unique
  type: UserType! @default(value: USER)
}

enum UserType {
  USER 
  ADMIN
}

ディレクティブの名前を変更

私たちのデータ構造は一度構築されて永久に使用されることはなく、最終的にはいくつかの変更が必要になります。 Prismaは、新しいプロパティとタイプの追加と削除についてはかなり優れていますが、それに依存するデータを既に保存しているタイプの名前を変更する場合は、いくつかの問題が発生する可能性があります。

@renameは一時的なディレクティブです。つまり、一度だけ使用し、スキーマを再デプロイしてから、datamodel.graphqlから削除します。

type User {
  id: ID! @id
  name: String!
  email: String!
  posts: [Content!]
}

type Content {
  id: ID! @id 
  title: String! @unique 
  body: String! 
  author: User!
}

Contentはかなりあいまいな名前です。@renameを使用して、もう少し明確な名前に変更しましょう。

type User {
  id: ID! @id
  name: String!
  email: String!
  posts: [Content!]
}

type Post @rename(oldName: "Content") {
  id: ID! @id 
  title: String! @unique 
  body: String! 
  author: User!
}

prismaフォルダーに移動し、スキーマを再デプロイします。

$ prisma deploy

これで、データを台無しにすることなく、@renameを安全に削除できます。

関係指令

ディレクティブで行う最も便利で一般的なことは、データ型間の関係を設定することです。

ストアから商品を削除した場合、データベースからその商品のすべてのレビューを削除する必要があることは明らかです。 その製品の所有者を削除する場合は、その製品とその後のレビューを削除します。 問題は、製品またはレビューが削除されたときにユーザーを削除したくないため、この階層を編成する特定の方法が必要なことです。

@relationディレクティブは、この問題を非常にエレガントに解決します。2つのタイプをリンクする名前を渡して、実行したいことを伝える必要がありますonDelete、削除を停止または続行しますチェーン。 CASCADEはチェーンの反対側のタイプを削除し、SET_NULLはそれを残します。

type User {
  id: ID! @id
  name: String!
  selling: [Product!] @relation(name: "UserToProduct", onDelete: CASCADE)
}

type Product {
  id: ID! @id 
  name: String!
  seller: User! @relation(name: "UserToProduct", onDelete: SET_NULL)
  reviews: [Review!] @relation(name: "ProductToReview", onDelete: CASCADE)
}

type Review {
  id: ID! @id 
  author: User! 
  review: String!
  product: Product! @relation(name: "ProductToReview", onDelete: SET_NULL)
}

まとめ

公式ドキュメントで確認する価値のあるオプションがさらにいくつかあります。