Open7
GraphQL
エクスクラメーションマーク(!マーク)の意味
エクスクラメーションマークがついているフィールドは、そのフィールドがnullになることがないことを意味
LaravelでのGraphQL開発
前提
下記ライブラリを利用
playgroundで動作確認
公式マニュアル:
ページネーションのカスタム
query {
TQuery(first:10, page:1) {
data{
title
genre
writer
}
paginatorInfo{
total
}
}
}
src/graphql/schema.graphql
type Query {
TQuery: [Test!]! @paginate(builder: "App\\GraphQL\\Queries\\TestQuery")
}
type Test {
title: String
writer: String
genre: Int
}
namespace App\GraphQL\Queries;
use Illuminate\Support\Facades\DB;
class TestQuery
{
public function __invoke($_, array $args)
{
return DB::table('test1')
->join('test2',[['test1.id', '=', 'test2.test1_id']])
->orderBy('test2.created_at', 'asc');
}
}
カラム単位にメソッドからデータ取得
app/GraphQL/Queries/xxx.php
namespace App\GraphQL\Queries;
class xxx
{
public function __invoke($_, array $args)
{
return $this;
}
public function test()
{
return 1111;
}
}
graphql/schema.graphql
type Query {
xxx: xxx
}
type xxx {
test: Int @method
}
apollo client
mutation {
createPost(input: { user_id: 1, content: "aaaaaaaaaa" }) {
user_id
content
}
}
mutation {
updatePost(id: 1, input: { user_id: 1, content: "bbbb" }) {
user_id
content
}
}
query {
posts(first:10, page:1) {
data{
user_id
content
}
paginatorInfo{
total
}
}
}
query {
posts(first:10, page:1) {
data{
user_id
content
user {
github_id
avatar_url
bio
}
}
paginatorInfo{
total
}
}
}
- 認証
- 認証されていないアクセスからすべてのフィールドを保護したい場合
- Laravelデフォルトで用意されているauth:api
- userテーブルのapi_tokenとAuthorizationヘッダを元に認証
- 認証されていないアクセスからすべてのフィールドを保護したい場合
github認証ログイン(通常の画面遷移の場合)
web.php
Route::get('/home', function () {
echo 'homeページ!!!!!!';
$user = Auth::user();
var_dump($user);
})->middleware('auth');
Route::get('/login', function () {
echo 'loginページ!!!!!!';
})->name('login');
Route::get('/login/github', function () {
return Socialite::driver('github')
->scopes(['read:user', 'public_repo'])
->redirect();
});
Route::get('/auth/github/callback', function () {
$githubUser = Socialite::driver('github')->user();
$user = User::where('github_id', $githubUser->id)->first();
if ($user) {
$user->update([
'name' => $githubUser->name,
'email' => $githubUser->email,
'bio' => $githubUser->user['bio'],
'avatar_url' => $githubUser->user['avatar_url'],
'github_token' => $githubUser->token,
'github_refresh_token' => $githubUser->refreshToken,
]); //プロフィール変更したら更新されるようにするため
} else {
$user = User::create([
'name' => $githubUser->name,
'email' => $githubUser->email,
'provider' => Provider::GITHUB,
'bio' => $githubUser->user['bio'],
'avatar_url' => $githubUser->user['avatar_url'],
'github_id' => $githubUser->id,
'github_token' => $githubUser->token,
'github_refresh_token' => $githubUser->refreshToken,
]);
}
Auth::login($user);
});
headerのauthorization指定
const client = new ApolloClient({
cache,
link: new HttpLink({
uri: 'http://localhost:4000/graphql',
headers: {
authorization: localStorage.getItem('token'),
},
}),
});
更新処理
const [updatePost, mutationResult] = useMutation<
UpdatePostData,
PostInputType
>(UPDATE_POST);
useMutaionの型
useMutation<
TData, // mutationが返すデータの型
TError, // mutationが返すエラーの型
TVariables, // muatate関数の変数の型
TContext // onMutate内でセットされるコンテキストの型
>
const handleSave = async () => {
await updatePost({
variables: {
params: {
id: parseInt(post.id),
title: post.title,
body: post.body,
},
},
});
mutationError
? alert(`Error: ${JSON.stringify(mutationError)}`)
: setMessage('Successfully saved');
};
useMutation
新規投稿した後に、一覧を更新することが簡単にできる
const { loading, error, data, fetchMore, refetch } = useQuery<PostsData>(POSTS_QUERY, {
variables: {
first: 100,
page: 1
}
});
const [createPost, { loading_cP, error_cP }] = useMutation(CREATE_POST,{
onCompleted() {
refetch();
},
});