generated at
ApolloのTutorialをやる
2021/5/27にやった
別projectに書いてたやつを移してきたmrsekut

ApolloのTutorialをやる

GraphQLよくわからんので触ってみる

server側のコードはどれぐらい書き換える必要があるのか
web/RNで共通の実装を使えるのか
clientはどういう実装になるのか
Entityとか
既存の実装からの移行はどれぐらい大変か





SpaceXの宇宙行き便へ搭乗予約をするためのアプリケーションを作る
GraphQL Serverは、
SQLiteとREST
を中継する
cloneしたやつにはstartとfinalディレクトリがある
finalは完成版。お手本
startに実装を追加していく。最終的にfinalになる
この構成良いなmrsekut
server/client両方書く
実装場所は別々



Apollo Srverをセットアップする
apollo-server graphql をinstall
Schemaを構築する
ここにSchemaを書く
js
const typeDefs = gql` # Your schema will go here `;
なんかのVSCode拡張入れないと色が付かないmrsekut
Launch は、1つのロケット発射情報的なやつ
こういうのをObject Typeというらしい
普通のtsの文脈におけるそれのことか?
gql
type Launch { id: ID! site: String mission: Mission rocket: Rocket isBooked: Boolean! }
! があるものがnon Null
null許容の方がデフォなんだ..mrsekut
gql
type User { id: ID! email: String! trips: [Launch]! token: String }
[] は配列
gql
type Mission { name: String missionPatch(size: PatchSize): String } enum PatchSize { SMALL LARGE }
missionPathは引数を取る
SMALLかLARGE
Query type
gql
type Query { launches: [Launch]! launch(id: ID!): Launch me: User }
見た目は同じだが、 Query という名のSchemaは扱いが特殊
1つ1つのfiledが、client目線のqueryになる
この例なら、clientは例えば me という問い合わせができる
APIのendpointみたいな感じ #??
あれ、なんか思ってたのと違うな?mrsekut
server sideで用意したAPI endpointじゃないと問い合わせできないの #??
なんかclientで適当にgraph qlのコード書いたらその形式のデータが自由に取れるものだと思ってたんだが
できるmrsekut
こんな感じで書く
query
query Query { me { id email trips { site mission { missionPatch name } } } }
Mutation type
これも特殊
gql
type Mutation { bookTrips(launchIds: [ID]!): TripUpdateResponse! cancelTrip(launchId: ID!): TripUpdateResponse! login(email: String): User }
データ変更するquery的なやつ
各fieldがendpointっぽい感じにならしい
Queryとか、Mutationって、fieldがめちゃくちゃ増えそうな気がするが、同名(QueryやMutation)で複数の型定義できるのか?



npm startでよく見る画面が出る



データソースをGraphQL APIにつなぎこむ
DataSource というclassを使う
RESTとDBをこれにつなげる
RESTと繋ぐ
apollo-datasource-rest RESTDataSource classをextendsして使う
追加の設定無しでcacheしてくれる
data sourceってなに #??
base urlってなに #??
this.get の基盤になるやつか
baseURL= https://google.com なら、 this.get('hoge') としたら、 http://google.com/hoge からfetchする感じ
上で定義した Query の各fieldに対応する実装を LaunchAPI classのmethodとして実装していく
RESTと繋ぐってそっちか〜mrsekut
そらそうか。
client→graphQL→ ここ →なんかのAPI server
ここ の部分を作っている
既存API Serverに対してGraphQLを接続しているので、こういう実装が必要になる
今作っているLaunchAPI内のmethodで、
RESTのresponse を、 さっき定義したGraphQL Schema に変換する実装を手動で書く
ってことは、API Serverは今後も作り続けないといけないの #??
何も嬉しくなっていない
たぶんこれはあとから説明される「DBとの接続」で解決されるはず
運営し続けたときの修正箇所メッチャ多くないか?
こういう実装のおかげでGraphQLとAPI Serverが疎結合になる
これ普通に外部APIサービス使っているって話だったmrsekut
忘れてた
https://api.spacexdata.com/v2/ は外部のサービスだ
これって結局、client目線で新しいAPI必要になったらServerも修正しないといけないのか #??
場合に依るか
DBと接続する
SQLiteとそのORMを使っている
UserAPI classはORMでSQLiteの中身をゴニョる実装を書いている
別にORMが必須というわけでもないだろうmrsekut
各methodに適合するSQLをそこに書けば同じことはできるはず
2つのDataSourceとApolloServerを接続する
今まで書いていたものは読み取り専用ってことかmrsekut
対象はRESTとDB
ちがう、queryを使って読み取りもできていない
わからんくなった、Data Sourceってなんだ #??
今まで書いていたものをresolversと呼ぶと思ってたがそういうわけではないんだなmrsekut



QueryのResolverを書く
これでようやくqueryで読み取りができるようになる
Resolver
GraphQL Schemaの1filedごとにfetchする関数を定義する?
だるそーmrsekut
これらの関数(resolver)は、Shcmeaで定義した型のデータか、Promiseを返す
各resolverのinterfaceは決まっている
e.g. fieldName: (parent, args, context, info) => data;
引数部分の型が決まっている
object型には入れ子関係があるが、親のresolverのほうが子より先に呼ばれる
Query のfieldと名前を合わせて定義する
js
Query: { launches: (_, __, { dataSources }) => dataSources.launchAPI.getAllLaunches(), launch: (_, { id }, { dataSources }) => dataSources.launchAPI.getLaunchById({ launchId: id }), me: (_, __, { dataSources }) => dataSources.userAPI.findOrCreateUser() }
これ別にQueryに限らず他のSchemaに対しても定義しないといけないらしい
でも全部やる必要はない
みづれーmrsekut
あ、でもこれでresolver完成7日
ここに出てくる getAllLaunches とかはさっきのDataSource定義したやつ
たぶん
contextを仲介してアクセスする
resolverを薄く保つのがベスプラらしい
resolverは定義してなくてもdefaultのものがある程度がんばってくれるらしい
どういうロジックかは知らん
allで返すのではなくpagenationできる
LaunchConnectionを使う
cursorは現在のindex
なぜString?


mutationのResolverを書く
ApploServerのcontextに指定する
この関数はclientがserverに送信するたびに呼ばれる
認証とかに使う

読んでない
Apollo Studioがどうのこうの


clientを見ていく
clientはtsなんだmrsekut
うわ、5を読んでないと無理やんけ
動かさずに読むだけにしよう


めちゃくちゃ雑に読んでる
Componentごとかなんかでquery書いて、useQueryで呼べばデータが取れる
ノリはSWRとかに近い
data, loading, errorとかも返してくれる
clientはメッチャ楽になるなmrsekut
まさにGraphQLという感じ
確かにうまくやればReduxとかは不要になりそう

もういいかな
残りは読んでない