この記事は 2023 年 10 月時点の記録です(2026 年 7 月 追記)
カスタムスカラーを定義して
makeSchemaのtypesに登録する、という流れは今も同じです。ただし使っているパッケージが引き継がれています。そして、そのことが本文の「動かなかった」箇所とも関係していそうです。1. graphql-iso-date は graphql-scalars に移りました
graphql-iso-dateのリポジトリには、「このリポジトリで定義されているスカラーは graphql-scalars リポジトリに移動し、そちらで保守される」と明記されています。npm 上の最新公開もかなり前で止まっています。yarn add graphql-scalars
@types/graphql-iso-dateも不要になります。graphql-scalarsは型定義を同梱しています。2.「NOT WORKING」の箇所について
本文では、次のコードをコメントアウトして「動かない」と書いています。
// ❌ NOT WORKING // import { asNexusMethod } from "nexus"; // export const DateTime = asNexusMethod(GraphQLDateTime, "date");
asNexusMethodは Nexus が公式に用意している仕組みで、既存の GraphQL スカラーを Nexus のメソッドとして使えるようにするものです。本来はこれが正攻法です。動かなかった原因は特定できていませんが、パッケージの組み合わせが関係している可能性があります。Nexus は内部で
graphqlパッケージのGraphQLScalarTypeを使うため、渡すスカラーが同じクラスのインスタンスである必要があります。graphql-iso-dateが古く、依存しているgraphqlのバージョンが食い違っていると、ここで噛み合わなくなります。実際、同じ時期に書いたJson 型の記事では、最初から
graphql-scalarsを使っており、asNexusMethodが問題なく動いています。パッケージの違いが原因だった可能性が高いと考えています。
graphql-scalarsに切り替えたうえで、次の形をお試しください。// src/graphql/DateTime.ts import { asNexusMethod } from 'nexus'; import { DateTimeResolver } from 'graphql-scalars'; export const DateTime = asNexusMethod(DateTimeResolver, 'dateTime');これが通ると、
objectTypeの中で次のように書けるようになります。t.nonNull.dateTime('createdAt'); // ← 型補完が効く本文の
t.nonNull.field("createdAt", { type: "DateTime" })でも動きますが、型名を文字列で書くことになるので、綴りを間違えても書いている最中には気づけません。Nexus を使う利点は型安全なので、可能ならメソッドの形にしておくほうが恩恵を受けられます。なお、
graphql-scalarsのDateTimeResolverは ISO-8601 準拠で、Prisma のDateTime型と同じ表現です。相性の面でも素直な選択になります。3. スカラーは types への登録を忘れずに
本文でも
src/graphql/index.tsから export していますが、makeSchemaのtypesに含まれていないとスキーマに現れません。「定義したのに型が見つからない」というときは、まずここを確認してください。Json 型でも同じです。※ 1 は 2026 年 7 月時点の公開情報に基づきます。2 は原因の推測を含み、当方の環境で再現・検証したものではありません。実装時はお使いのバージョンの公式ドキュメントとあわせてご確認ください。
Prisma チームは現在、nexus-plugin-prisma の長期的に保守できるようにプラグインを書き直しているため、DateTimeタイプはサポートされていません。
そもそも、DateTime 型は GraphQL (または Nexus) でネイティブにサポートされていないため、最初にそれを GraphQL スキーマに追加する必要があります。 GraphQL スカラーの標準 ISO 日付実装は、graphql-iso-date npm パッケージから使用できます。
まず、パッケージをプロジェクトに追加します。
パッケージを追加する
try🐶everything backend$ yarn add graphql-iso-date try🐶everything backend$ yarn add @types/graphql-iso-date --dev
新しい Types を指定する
以前記事の src/schema.ts を下記のように変更します。(Line 5、8)
// src/schema.ts
import { makeSchema } from "nexus";
import { join } from "path";
import * as types from "./graphql";
export const schema = makeSchema({
types,
outputs: {
typegen: join(__dirname, "generated", "nexus-typegen.ts"),
schema: join(__dirname, "generated", "schema.graphql"),
},
});
DateTime タイプを定義する
src/graphql/DateTime.ts を作成します。
// src/graphql/DateTime.ts
import { GraphQLDateTime } from "graphql-iso-date";
export const DateTime = GraphQLDateTime;
// ❌ NOT WORKING
// import { asNexusMethod } from "nexus";
// export const DateTime = asNexusMethod(GraphQLDateTime, "date");
src/graphql/index.ts を作成します。
// src/graphql/index.ts
export { DateTime } from "./DateTime";
export { Post } from "./Post";
export { Profile } from "./Profile";
export { User } from "./User";
DateTime タイプを適用する
createdAt、updatedAt フィルドに DateTime 型を適用します。(Line 9-10、23-24)
src/graphql/Post.ts を作成します。
// src/graphql/Post.ts
import { objectType } from "nexus";
/*
*** Prisma type ***
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
}
*/
export const Post = objectType({
name: "Post",
definition(t) {
t.nonNull.int("id");
t.nonNull.field("createdAt", { type: "DateTime" });
t.nonNull.field("updatedAt", { type: "DateTime" });
t.nonNull.string("title");
t.string("content");
t.boolean("published");
t.field("author", {
type: "User",
resolve: (parent, _, ctx) => {
return ctx.prisma.user.findUnique({ where: { id: parent.id } }).user();
},
});
},
});


コメント