Open KeihakuOh opened 2 days ago
const mutation = new GraphQLObjectType({
name: 'Mutation',
fields: {
addUser: {
type: UserType,
args: {
firstName: { type: new GraphQLNonNull(GraphQLString) },
age: { type: GraphQLInt },
companyId: { type: GraphQLString }
},
resolve(parentValue, { firstName, age, companyId }) {
return axios.post('http://localhost:3000/users', { firstName, age, companyId })
.then(res => res.data);
}
}
}
});
GraphQLNonNullはnullだと許せないって意味
type: UserType, // ここでミューテーションの戻り値がUserTypeであることを指定
nameを定義する必要性:
{
user(id: "123") {
firstName
age
company {
name
}
}
}
このクエリで使われている user フィールドの型は UserType です。UserTypeの name: 'User' がスキーマ内で指定されていることで、GraphQLはこのクエリが User 型に基づいたデータを要求していると理解します。
Lokkaは、シンプルで軽量なGraphQLクライアントです。比較的古いライブラリであり、状態管理やキャッシングの機能は提供していませんが、シンプルさが魅力
const { Lokka } = require('lokka');
const { Transport } = require('lokka-transport-http');
// GraphQLエンドポイントを指定してクライアントを作成
const client = new Lokka({
transport: new Transport('https://your-graphql-endpoint.com/graphql')
});
// クエリを送信し、データを取得
client.query(`
{
user(id: "1") {
name
email
}
}
`).then(result => {
console.log(result);
}).catch(error => {
console.error(error);
});
特徴 状態管理(Apollo Clientを使ったローカル状態の管理) 高度なキャッシング リアルタイムのサブスクリプションサポート リアクティブなUIと親和性が高い(Reactなどとの統合がスムーズ)
import { ApolloClient, InMemoryCache, gql, ApolloProvider, useQuery } from '@apollo/client';
// Apollo Clientの設定
const client = new ApolloClient({
uri: 'https://your-graphql-endpoint.com/graphql',
cache: new InMemoryCache(),
});
// クエリを定義
const GET_USER = gql`
query GetUser($id: ID!) {
user(id: $id) {
name
email
}
}
`;
// コンポーネントでクエリを実行
function User({ userId }) {
const { loading, error, data } = useQuery(GET_USER, {
variables: { id: userId },
});
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<div>
<h1>{data.user.name}</h1>
<p>{data.user.email}</p>
</div>
);
}
// アプリケーション全体にApolloProviderを適用
function App() {
return (
<ApolloProvider client={client}>
<User userId="1" />
</ApolloProvider>
);
}
export default App;
Relayは、Facebookが開発した高度に最適化されたGraphQLクライアントで、大規模なアプリケーションやパフォーマンスが重要な場面でよく使われます。Apolloに比べてやや複雑ですが、効率的なデータ取得、キャッシング、パフォーマンスの最適化が特徴です。
どっちがいいとかはないが、apolloの方は将来変動ありそう
// Apollo Serverのインポート
const { ApolloServer, gql } = require('apollo-server');
// サンプルユーザーデータ
const users = [
{ id: '1', name: '太郎', email: 'taro@example.com' },
{ id: '2', name: '花子', email: 'hanako@example.com' },
];
// GraphQLスキーマの定義
const typeDefs = gql`
type User {
id: ID!
name: String!
email: String!
}
type Query {
user(id: ID!): User
users: [User]
}
`;
// リゾルバの定義
const resolvers = {
Query: {
// 特定のIDに基づいてユーザー情報を取得
user: (parent, args) => users.find(user => user.id === args.id),
// すべてのユーザー情報を取得
users: () => users,
},
};
// Apollo Serverを作成
const server = new ApolloServer({ typeDefs, resolvers });
// サーバーの起動
server.listen().then(({ url }) => {
console.log(`🚀 サーバーが起動しました: ${url}`);
});
const graphql = require('graphql');
const axios = require('axios');
const {
GraphQLObjectType,
GraphQLString,
GraphQLInt,
GraphQLSchema,
GraphQLList,
GraphQLNonNull,
} = graphql;
const CompanyType = new GraphQLObjectType({
name: 'Company',
fields: () => ({
id: { type: GraphQLString },
name: { type: GraphQLString },
description: { type: GraphQLString },
users: {
type: new GraphQLList(UserType),
resolve(parentValue, args) {
return axios
.get(`http://localhost:3000/companies/${parentValue.id}/users`)
.then((res) => res.data);
},
},
}),
});
const UserType = new GraphQLObjectType({
name: 'User',
fields: () => ({
id: { type: GraphQLString },
firstName: { type: GraphQLString },
age: { type: GraphQLInt },
company: {
type: CompanyType,
resolve(parentValue, args) {
return axios
.get(`http://localhost:3000/companies/${parentValue.companyId}`)
.then((res) => res.data);
},
},
}),
});
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
user: {
type: UserType,
args: { id: { type: GraphQLString } },
resolve(parentValue, args) {
return axios
.get(`http://localhost:3000/users/${args.id}`)
.then((resp) => resp.data);
},
},
company: {
type: CompanyType,
args: { id: { type: GraphQLString } },
resolve(parentValue, args) {
return axios
.get(`http://localhost:3000/companies/${args.id}`)
.then((resp) => resp.data);
},
},
},
});
const mutation = new GraphQLObjectType({
name: 'Mutation',
fields: {
addUser: {
type: UserType,
args: {
firstName: { type: new GraphQLNonNull(GraphQLString) },
age: { type: GraphQLInt },
companyId: { type: GraphQLString },
},
resolve(parentValue, { firstName, age, companyId }) {
return axios
.post('http://localhost:3000/users', { firstName, age, companyId })
.then((res) => res.data);
},
},
deleteUser: {
type: UserType,
args: {
id: { type: new GraphQLNonNull(GraphQLString) },
},
resolve(parentValue, { id }) {
return axios
.delete(`http://localhost:3000/users/${id}`)
.then((res) => res.data);
},
},
editUser: {
type: UserType,
args: {
id: { type: new GraphQLNonNull(GraphQLString) },
firstName: { type: GraphQLString },
age: { type: GraphQLInt },
companyId: { type: GraphQLString },
},
resolve(parentValue, args) {
return axios
.patch(`http://localhost:3000/users/${args.id}`, args)
.then((res) => res.data);
},
},
},
});
module.exports = new GraphQLSchema({
mutation,
query: RootQuery,
});
GraphQL Expressについて
Expressサーバーは、複数のルート(例えば、/, /api, /graphql など)を設定できます。GraphQL Expressは、このルートの1つとしてGraphQLの機能を提供します。GraphQL Express自体はサーバではなく、Expressサーバの中で動作するルートミドルウェアです。したがって、GraphQL Expressだけではサーバとは言えません。GraphQL Expressを使うには、必ずExpressサーバが動作している必要があり、GraphQLはそのサーバの一部として機能します。
ーーーーーー より広義のサーバの定義: ソフトウェアサーバ: 例えば、ExpressやNode.jsなどのサーバアプリケーションは、ポート番号を監視し、HTTPリクエストを受け付けてレスポンスを返します。ポート番号をリッスンして、ネットワーク経由でアクセスできるサービスを提供する場合が多い。 物理サーバ: データセンターなどに設置され、複数のサーバアプリケーションを動作させるための実際のコンピュータ。 仮想サーバ: 物理サーバ上で仮想的に動作し、複数のサーバを1つの物理サーバで運用できるもの。
import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
// Apollo Client を作成
const client = new ApolloClient({
uri: 'https://example.com/graphql', // 自分のGraphQLサーバーのURL
cache: new InMemoryCache() // キャッシュの設定
});
ReactDOM.render(
<ApolloProvider client={client}>
<App />
</ApolloProvider>,
document.getElementById('root')
);
Apollo Provider は、React コンポーネントに GraphQL サーバーと通信するための Apollo Client を使えるようにするためのもの。
import React, { Component } from 'react';
import gql from 'graphql-tag';
import { graphql } from 'react-apollo';
class SongList extends Component {
renderSongs() {
if (this.props.data.loading) {
return <div>Loading...</div>;
}
return this.props.data.songs.map(song => {
return <li key={song.title}>{song.title}</li>;
});
}
render() {
return (
<div>
<ul>
{this.renderSongs()}
</ul>
</div>
);
}
}
const query = gql`
{
songs {
title
}
}
`;
export default graphql(query)(SongList);
graphql(query) は Apollo Client が提供する HOC 関数を返します。 その返された HOC 関数に SongList を渡すことで、Apollo Client は SongList コンポーネントに自動的に GraphQL のデータフェッチ機能を追加します。 結果として、SongList コンポーネントは props を通してデータを受け取り、そのデータを表示できます。
↑これができるのはApolloProviderのおかげ
Query Fragments(クエリフラグメント) は、GraphQLのクエリ内で再利用可能な部分