GraphQLを試してみました
(注意)本記事は2020年09月時点の情報です。
0. 参考
- 初めてのGraphQL ―Webサービスを作って学ぶ新世代API
- Spring Boot + GraphQLでAPIを作成してみよう!
1. GraphQLとは?
- 数学のグラフ理論に基づく(グラフ理論:一筆書き問題などの学問)
- Web APIのためのクエリ言語
- 様々な言語で実装可能
- RESTの課題を解決しようとした
- Facebookが2015年に公開
インスタグラムでのイメージ
その前にREST APIとの比較
- スターウォーズAPI(REST版)
curl https://swapi.dev/api/people/1/
レスポンス
{
"name": "Luke Skywalker",
"height": "172",
"mass": "77",
"hair_color": "blond",
~省略~
"gender": "male",
"homeworld": "http://swapi.dev/api/planets/1/",
"films": [
"http://swapi.dev/api/films/1/",
"http://swapi.dev/api/films/2/",
"http://swapi.dev/api/films/3/",
"http://swapi.dev/api/films/6/"
],
~省略~
"url": "http://swapi.dev/api/people/1/"
}
- スターウォーズAPI(GraphQL版)
curl https://swapi.apis.guru/ -ContentType application/json -Body '{"query":"{person(personID:1){name,gender,filmConnection{films{title}}}}"}'
クエリの部分だけ整形すると
これがGraphQLのクエリ!
{query:
{person(personID:1)
{name,
gender,
filmConnection
{films
{title}
}
}
}
}
レスポンス
{
"data": {
"person": {
"name": "Luke Skywalker",
“gender”: “male”,
"filmConnection": {
"films": [
{
"title": "A New Hope"
},
{
"title": "The Empire Strikes Back"
},
{
"title": "Return of the Jedi"
},
{
"title": "Revenge of the Sith"
}
]
}
}
}
}
RESTとGraphQLを比較すると
- RESTは多様なエンドポイントURI
- RESTは過剰取得
- GraphQLは階層構造も取得
- GraphQLは日本語情報が少ない
- GraphQLはライブラリ・ツール類がReactなどのjs系が中心
2. GraphQLの言語仕様
書籍にお任せして、省略
3. GraphQL+SpringDataJDBCを使ってPostgreSQLからデータ取得
依存関係
- SpringInitializrでBoot、Gradle、SpringDataJDBC
- PostgreSQLのjdbc4.jar
- GraphQL系↓
// 必須
implementation "com.graphql-java-kickstart:graphql-spring-boot-starter:7.1.0“
// 任意(ブラウザ上でクエリを書ける便利ツール)
implementation "com.graphql-java-kickstart:graphiql-spring-boot-starter:7.1.0"
Entityクラス
- Authテーブル
public class Auth {
@Id
private long auth_id;
private long person_id;
private String login_id;
private String pass_modify_date;
~getter/setter~
}
Repositoryクラス
- GraphQL関係ない。SpringDataJDBCの書き方。実装クラス不要
public interface AuthRepository
extends CrudRepository<Auth, Long> {
}
Resolverクラス
@Component
public class AuthResolver implements GraphQLQueryResolver {
private final AuthRepository repository;
@Autowired
public AuthResolver(AuthRepository repository) {
this.repository = repository;
}
public Auth getUserById(long auth_id) {
// Spring Data JDBCでDBアクセス
Optional<Auth> optAuth = repository.findById(auth_id);
Auth result = optAuth.orElse(new Auth());
return result;
}
}
スキーマ定義
type Auth {
auth_id: ID!
person_id: Int
login_id: String
pass_modify_date: String
}
type Query {
getUserById(auth_id: ID!): Auth
}
実行例
- 実行クエリ
query{
getUserById(auth_id:100) {
auth_id
person_id
login_id
pass_modify_date
}
}
- レスポンス
{
"data": {
"getUserById": {
"auth_id": "100",
"person_id": 1111111111,
"login_id": "kyotokyoto@test.test",
"pass_modify_date": "2021-05-24 18:00:00.000"
}
}
}
4. おわりに
- (このレベルのデモであれば)割と簡単に実装できた
- 実際にエンタープライズで導入する際は、色々カベはありそう
- GraphQLのクエリを書くのは楽しい
- RESTfull APIを設計する時の悩みは確かに解消される気がする
- Javaだとまだライブラリや情報が少ないかも
- 個人的にはもう少し流行って欲しいな~