SolidJSでGraphQL扱いたいあなたへ…
SolidJS×GraphQL
SolidjsでGraphQLを扱う時の手順を紹介していこうと思います。
SolidJSプロジェクト作成する
degitを使ってテンプレートをダウンロードしてきます。
$ npx degit solidjs/templates/ts my-app
$ cd my-app
$ npm i
これだけですでにアプリが立ち上がってくるようになっています。
$ npm run dev
ブラウザで http://localhost:3000
でアクセスして画面が表示されればOKです。
GraphQL Code Generator
GraphQLのスキーマファイルからTypeScriptの型定義ファイルを生成するパッケージにGraphQL Code Generatorを利用します。
$ npm i graphql
$ npm i -D @graphql-codegen/cli
初期化します
$ npx graphql-codegen init
Welcome to GraphQL Code Generator!
Answer few questions and we will setup everything for you.
? What type of application are you building? (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to proceed)
Application built with other framework or vanilla JS
? Where is your schema?: (path or url) (http://localhost:4000)
schema.graphql
? Where are your operations and fragments?: (src/**/*.graphql)
src/**/*.tsx
? Pick plugins: (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to proceed)
TypeScript Operations (operations and fragments)
? Where to write the output: (src/generated/graphql.ts)
src/generated/graphql.d.ts
? Do you want to generate an introspection file?
Yes
? How to name the config file?
codegen.yml
? What script in package.json should run the codegen?
graphql-codegen
生成された codegen.yml
を少し書き換えます
overwrite: true
schema: "schema.graphql"
generates:
src/generated/graphql.d.ts:
plugins:
- "typescript-operations"
./graphql.schema.json:
plugins:
- "introspection"
下記の内容で仮のスキーマファイルを作成します
type Hello {
message: String!
}
type Query {
hello: Hello!
}
生成コマンドを実行します
$ npm run graphql-codegen
成功したらプロジェクト直下に graphql.schema.json
というファイルが生成されていると思います。
@solid-primitives/graphql
SolidJSでGraphQLを簡単に扱うために@solid-primitives/graphqlを利用します。
npm i @solid-primitives/graphql
App.tsx
でGraphQLのQuery文を書き加えます。
import type { Component } from "solid-js";
// 追加
import { gql } from "@solid-primitives/graphql";
import logo from "./logo.svg";
import styles from "./App.module.css";
// 追加
const helloQueryDocument = gql`
query hello {
hello {
message
}
}
`;
const App: Component = () => {
// 省略
};
export default App;
codegen.yml
を書き換えます。
overwrite: true
schema: "schema.graphql"
documents: "./src/**/*.tsx" // 追加
generates:
src/generated/graphql.d.ts:
plugins:
- "typescript" // 追加
- "typescript-operations"
./graphql.schema.json:
plugins:
- "introspection"
追加で必要になるパッケージのインストールします。
$ npm i -D @graphql-codegen/typescript
再度型定義ファイルを生成します。
$ npm run graphql-codegen
成功すると ./src/generated/graphql.d.ts
が生成されています。
export type Maybe<T> = T | null;
export type InputMaybe<T> = Maybe<T>;
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
ID: string;
String: string;
Boolean: boolean;
Int: number;
Float: number;
};
export type Hello = {
__typename?: 'Hello';
message: Scalars['String'];
};
export type Query = {
__typename?: 'Query';
hello: Hello;
};
export type HelloQueryVariables = Exact<{ [key: string]: never; }>;
export type HelloQuery = { __typename?: 'Query', hello: { __typename?: 'Hello', message: string } };
この型定義を使ってSolidJSのアプリからGraphQLを扱います。
import type { Component } from "solid-js";
// createGraphQLClientを追加
import { gql, createGraphQLClient } from "@solid-primitives/graphql";
// 追加
import { HelloQuery } from "./generated/graphql";
import logo from "./logo.svg";
import styles from "./App.module.css";
const helloQueryDocument = gql`
query hello {
hello {
message
}
}
`;
const App: Component = () => {
// 追加
// GraphQLサーバのエンドポイント
const newQuery = createGraphQLClient("http://localhost:8080/graphql");
const [data] = newQuery<HelloQuery>(helloQueryDocument);
return (
<div class={styles.App}>
<header class={styles.header}>
<img src={logo} class={styles.logo} alt="logo" />
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<a
class={styles.link}
href="https://github.com/solidjs/solid"
target="_blank"
rel="noopener noreferrer"
>
Learn Solid
</a>
// 追加
<div>{data()?.hello.message}</div>
</header>
</div>
);
};
export default App;
ちなみに newQuery
の返り値にはrefetchが返ってくるので、このコンポーネント内で同じAPIを叩きたい場合はこのrefetchを使うのが良かったりします。
まとめ
これでGraphQLサーバーに対してアクセスできるようになりました。
GraphQLCodeGeneratorでGraphQLスキーマから型定義ファイルを生成して、@solid-primitives/graphqlを使ってGraphQLを扱うという感じです。
GraphQLサーバーを立てるのはまた別記事で書こうと思います。(いつ書くかはわかりませんが…)
ではまた!!!
Discussion