前回は、Prismaを使って、PostgresSQLデータベースと接続しました。

今回は、Prismaを使って、PostgresSQLデータを取得します。

コードは、前回のコードを使用します。

スキーマを指定する

prismaフォルダのschema.prismaファイルに、スキーマを指定します。

まず、Booksというmodelを作成します。

model Book {
}

idを作成します。

idの型を指定します。

idの型は整数にしたいので、Intを指定します。

model Book {
  id Int 
}

prismaでIDを認識するために、@idを指定します。

model Book {
  id Int @id
}

毎回IDを指定したくないので、自動で取得できる様にするために、autoincrementを設定します。

model Book {
  id Int @id @default(autoincrement())
}

title、author、categoryIdを指定します。

また、インデントを揃えると、見やすくなります。

model Book {
  id         Int    @id @default(autoincrement())
  title      String
  author     String
  categoryId Int
}

isReadは、デフォルトでfalseを指定します。

model Book {
  id         Int     @id @default(autoincrement())
  title      String
  author     String
  categoryId Int
  isRead     Boolean @default(false)
}

作成日を作成します。

作成日は、デフォルトで、nowを指定します。

model Book {
  id         Int      @id @default(autoincrement())
  title      String
  author     String
  categoryId Int
  isRead     Boolean  @default(false)
  createdAt  DateTime @default(now())
}

Bookと同様に、Categoryも作成します。

model Category {
  id        Int
  name      String
}

では、一度テーブルを作成します。

テーブルを作成するには、ターミナルでnpx prisma db pushを実行します。

image2

テーブルが作成されました。

作成されたかどうかを確認します。

ターミナルで、npx prisma studioを実行します。

image3

自動で、ブラウザが開きました。

Bookをクリックしてみると、

image4

先ほど作成したテーブル名が表示されました。

リレーションシップを作成する

次は、BookとCategoryの関係を確立します。

BookのcategoryIdとCategoryのidを紐付けます。

BookのcategoryIdの下にcategoryを設定しましょう。

model Book {
  id         Int      @id @default(autoincrement())
  title      String
  author     String
  isRead     Boolean  @default(false)
  createdAt  DateTime @default(now())
  categoryId Int
  category
}

categoryの中身は、Categoryなので、型はCategoryを指定します。

model Book {
  id         Int      @id @default(autoincrement())
  title      String
  author     String
  isRead     Boolean  @default(false)
  createdAt  DateTime @default(now())
  categoryId Int
  category   Category
}

relationを使って紐付けます。

Bookの対象は、categoryIdなので、fieldscategoryIdを指定します。

Categoryの対象は、idなので、referencesidを指定します。

model Book {
  id         Int      @id @default(autoincrement())
  title      String
  author     String
  isRead     Boolean  @default(false)
  createdAt  DateTime @default(now())
  categoryId Int
  category   Category @relation(fields: [categoryId], references: [id])
}

Categoryでは、booksを設定します。

booksには、Book[]を指定します。

model Category {
  id         Int      @id @default(autoincrement())
  name       String
  books      Book[]
}

では、再度ブラウザで確認します。

prisma studioを解除して、ターミナルでnpx prisma db pushを実行します。

npx prisma studioを実行します。

image5

Bookにcategoryが追加されました。

image6

Categoryにもbooksが追加されています。

BookとCategoryにデータを入れてみます。

image7

image8

BookとCategoryの関係は、問題なく確立されています。

PostgresのデータをGraphQLで取得する

最後に、PostgresのデータをGraphQLで取得します。

まずは、index.tsで、PrismaClientPrismaをインポートします。

import { PrismaClient, Prisma } from "@prisma/client"

Postgresのデータベースを接続するために、PrismaClientを呼び出します。

const prisma = new PrismaClient();

server内のdbprismaに置き換えます。

const server = new ApolloServer({
  typeDefs,
  resolvers: {
    Query,
    Mutation,
    Category,
    Book,
  },
  context: {
    prisma,
  },
});

contextの型を作成しておきます。

export type Context = {
  prisma:  PrismaClient<Prisma.PrismaClientOptions, never, Prisma.RejectOnNotFound | Prisma.RejectPerOperation>
}

次に、shema.tsのスキーマを、schema.prismaで作成した型に合わせます。

const { gql } = require("apollo-server");

export const typeDefs = gql`
  type Query {
    books(filter: BooksInput): [Book!]!
    book(id: Int!): Book
    categories: [Category!]!
    category(id: ID!): Category
  }

  type Mutation {
    addBook(input: AddBookInput!): Book!
    deleteBook(id: Int!): Boolean!
    updateBook(id: Int!, input: UpdateBookInput!): Book!
  }

  type Book {
    id: Int!
    title: String!
    author: String!
    createdAt: String!
    category: Category!
  }

  type Category {
    id: Int!
    name: String!
    books: [Book!]!
  }

  input BooksInput {
    isRead: Boolean
  }

  input AddBookInput {
    id: Int!
    title: String!
    author: String!
    categoryId: Int!
    isRead: Boolean!
  }

  input UpdateBookInput {
    id: Int
    title: String
    author: String
    categoryId: Int
    isRead: Boolean
  }
`;

resolversフォルダのQuery.tsを開きます。

books内のdbをprismaへ変換します。

また、parentとfilterは、取り敢えず『_』にしておきましょう。

books: (_, _, { prisma }) => {
  let filteredBooks = db.books;
  if (filter) {
    if (filter.isRead === true) {
      filteredBooks = filteredBooks.filter((book) => {
        return book.isRead;
      });
    }
  }

  return filteredBooks;
},

prismaに型指定をします。

型は、先ほど作成したContextを使用します。

books: (_: any, __: any, { prisma }: Context) => {
  let filteredBooks = db.books;
  if (filter) {
    if (filter.isRead === true) {
      filteredBooks = filteredBooks.filter((book) => {
        return book.isRead;
      });
    }
  }

  return filteredBooks;
},

prismaのfindManyを使って、一覧を取得します。

books: (_: any, __: any, { prisma }: Context) => {
  return prisma.book.findMany();
},

では、GraphQLのサーバーを起動して、ブラウザで確認します。

image9

『addBooks』をクリックすると、

image10

Postgresのデータを取得することができました。

以下が、全文です。

次回は、リゾルバ内を整形して、特定のPostgresSQLデータを取得します

ブログ一覧