こんにちは、la belle vieでエンジニアをしていますTanabuと申します。
弊社はGILT、GLADD、White Labelの3つのサービスを運営しています。
この3つのサービスを統合するプロジェクトを私が担当しており、GraphQLの利用をしたく実装調査などを進めています。
なぜGraphQL?
弊社のサービスは大量のAPIサービスが連携することで成り立っており、
フロント、バックエンド、またはAPI同士が複雑に呼び合い保守・改修が非常に難しくなっている現状があります。
このAPIはどういった仕様で、どういう風に呼び出しをし何を返却するか分からない・・・そんな事はありませんか?
GraphQLを導入することによって、呼び出しを /graphql にまとめ、開発、仕様把握、保守を楽にしたいと思った為です。
今回はモックの作成を行い、実装出来たことや気づいた事などを書こうと思います。拙い文章ですがご容赦お願いします🙇♂️
利用したフレームワーク
Laravel + Lighthouse
Lighthouse公式はこちら
https://lighthouse-php.com/tutorial/#what-is-lighthouse
スキーマをモデル単位で分けたい
- schema.graphql を以下内容にする
- ポイントは、#import **/*.graphq の部分、各モデル用のクエリ・ミューテーションの書かれているファイルのパスにする
type Query
type Mutation
#import **/*.graphql
- モデル用のgraphqlを以下内容へ変更する
- ポイントは、extend と #models/user.graphql の部分
- 例:user.graphql
# models/user.graphql
extend type Query {
me: User @auth
}
extend type Mutation {
createUser (
input: CreateUserInput! @spread
): User @create
}
リレーションを利用したクエリを作りたい
Laravelでモデルリレーションをする際、$this->hasMany のような関連付けをしますが、Laravel + lighthouse も同様に関連付をするとクエリで引っ張って来れるようになります。
例:User.php
public function posts(): HasMany
{
return $this->hasMany(Post::class, 'user_id');
}
例:user.graphql
type User {
id: ID!
name: String!
posts: [Post!]! @hasMany
}
// Postはpost.graphqlに以下で記載
type Post {
id: ID!
title: String!
content: String!
user: User! @belongsTo
}
ログイン・ログアウトを作りたい (token)
- ログイン、ログアウト処理を実装
AuthResolver.php
public function login($_, array $args): string|null
{
$credentials = Arr::only($args, ['email', 'password']);
$guard = Auth::guard(config('api'));
if ($guard->once($credentials)) {
$token = Auth::user()->createToken('user_token');
return $token->plainTextToken;
}
return null;
}
public function logout(): void
{
Auth::guard(config('api'))->user()->tokens()->delete();
}
- mutationにクエリを追加
user.graphql
extend type Mutation {
login(email: String!, password: String!): String @field(resolver: "AuthResolver@login")
logout: User @guard @field(resolver: "AuthResolver@logout")
}
クエリに対しテストを行いたい
- graphQLテスト用にフォルダ分けを行う
- testsフォルダ配下にGraphQLフォルダを配置
- phpunit.xml の testsuites に以下を追加
<testsuite name="GraphQL">
<directory suffix="Test.php">./tests/Graphql</directory>
</testsuite>
- graphQLトレイトとassertJsonトレイトを利用しクエリのテストを行う
$this->graphQL('
query ($id: ID!) {
user(id: $id) {
id
email
}
}', [
'id' => $user->id
])->assertJson([
'data' => [
'user' => [
'id' => $user->id,
'email' => $user->email
]
]
]);
感想
基本公式のドキュメントを読み、Laravel経験者であればすんなり実装は完成させる事が出来そうです。
Eloquentモデルを作成し、必要であればリレーションを張り、クエリを作成すれば完成するので、Lighthouseがいかに楽に実装出来るよう作られているか分かります。
Laravel sail でコンテナも楽に作成出来ますし、PHPにてGraphQLの開発を行いたい場合は学習コストの少ないこちらの環境がオススメではないでしょうか。
ではまた!