Edited at
Go4Day 9

graphql-goでブログAPIを作った話 #golang

Go4 Advent Calendar 2018 の記事です。

GolangでGraphQLを使用したブログのAPIを作ったので、その知見を晒そうと思います。

※ソースの解説等は長くなってしまうのでしていません。気になるかたはGithubのぞいてください。不明点等はDMくだされば解説します。


ソースコード

trrrrrys/blogapi: blog api


出来たもの

下記クエリを投げると

{

user{
description
email
name
nick_name
}
contents(limit: 1) {
id
author
title
publish_date
tags {
tag_desc
tag_name
}
body
}
}

こんな感じのデータが帰ってきて

{

"data": {
"contents": [
{
"author": "trrrrrys",
"body": "#たいとるが決まりません",
"id": 1,
"publish_date": 1544193955,
"tags": [
{
"tag_desc": "",
"tag_name": "go"
}
],
"title": "ブログのタイトルをどうしようかなと思っている"
}
],
"user": {
"description": "4649",
"email": "tsukahararu@gmail.com",
"name": "Ryo Tsukahata",
"nick_name": "trrrrrys"
}
}
}

こんな感じのcurlでコンテンツ作成できる。

curl -X POST \

https://{url}/v1/contents \
-H 'Authorization: Bearer {とーくん}' \
-H 'Content-Type: application/json' \
-d '{
"title" : "ブログのタイトルをどうしようかなと思っている",
"tags": [
"go"
],
"body":"#たいとるが決まりません"
}'

訳ありのため, mutationでコンテンツ作成は諦めました。


構成


インフラ


  • GAE/Go111

  • Datastore

GAE Second generation(Go1.11) を使用しました。

これにより、appengineパッケージから解放されました。

datastoreも

google.golang.org/appengine/datastore

ではなく

cloud.google.com/go/datastore

を使用しています。


GraphQLライブラリ

GraphQLの実装には以下のライブラリを使用しました。


開発してわかったこと


エンドポイント考える必要がない

これはGraphQLの利点ですが、

RESTfulであれば、エンドポイント考えるの割と大変なので良いと思います。


GUIが便利

GraphQLにはGUIがあります。

graphql-goの場合は/graphql,

Electronで作られているデスクトップアプリケーションもあります。(https://electronjs.org/apps/graphiql)

GraphQLのGUIはスキーマ定義を参照しているようで、

こんな感じでリクエスト時のフィールドの自動補完が出来ます。


スキーマ定義からコード生成できない

これかなり重大です。

graphql-goでスキーマ定義するのはなかなか面倒です。

var userType = graphql.NewObject(

graphql.ObjectConfig{
Name: "user",
Fields: graphql.Fields{
"name": &graphql.Field{
Type: graphql.String,
},
"nick_name": &graphql.Field{
Type: graphql.String,
},
"email": &graphql.Field{
Type: graphql.String,
},
"description": &graphql.Field{
Type: graphql.String,
},
},
},
)

99designs/gqlgen このライブラリだとスキーマ定義からコード生成されるらしいですが、使ってないのでわかりません。


一部機能のみ認証実装するのが面倒

一覧取得は誰でもできるが、投稿は認証させたい

みたいなケースでとても不便です。

GraphQLは/graphqlというエンドポイントしか存在しないため、

エンドポイントごとにミドルウェアで認証を実施するといったことができません。

mutationのみ認証実装しようとしても、

query, mutationはどちらもPOSTリクエストで送られてくるためヘッダでの判別は不可能です。

ミドルウェアで認証する際にBodyの中身を確認しないといけないのはかなり不便です。

かといって、ハンドラで認証するのも微妙です。

面倒だったので、

今回はGraphQLAPIとは別に投稿用のAPIを作りました。


ヘルスチェック

jsのApolloっていうライブラリだと、ヘルスチェックの別途エンドポイントを用意してくれる模様。

What's new? | Apollo Server

HandlerFuncで作れば良いのかなと思います。


課題


Datastore設計の見直し

ユーザをmodelにそのまま書いたりしてます。

さすがに適当すぎました。

時間を見つけて見直そうかなと思います。


Json内にMarkdownファイル埋め込めない問題

Markdown内にダブルクォート等があった場合そのままcurlで投げれない。

さすがに投げるたびにエスケープするのは面倒なので、cliツールを作ろうかなと思ってます。


まとめ

GraphQLは楽しい。

特に普段からAPI作ってる人とかはとても楽しいと思います。

サービスの本番運用に耐えられるかはパフォーマンス測ってみないとわからないですが。


おしまい

かなり質素な記事になってしまいました。

(最近忙しくてこれが精一杯でした。。)

まだurl先には何もありませんが

作ったブログも近々公開予定なので

そちらもよろしくお願いします。

https://blog.trrrrrys.com

質問や、マサカリ大歓迎ですので、コメントor僕のTwitterまでお願い致します。