0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

GraphQL+SpringDataJDBCを試してみた

Last updated at Posted at 2021-05-23

GraphQLを試してみました

(注意)本記事は2020年09月時点の情報です。

0. 参考

  • 初めてのGraphQL ―Webサービスを作って学ぶ新世代API

  • Spring Boot + GraphQLでAPIを作成してみよう!

1. GraphQLとは?

  • 数学のグラフ理論に基づく(グラフ理論:一筆書き問題などの学問)
  • Web APIのためのクエリ言語
  • 様々な言語で実装可能
  • RESTの課題を解決しようとした
  • Facebookが2015年に公開

インスタグラムでのイメージ

image.png

その前に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だとまだライブラリや情報が少ないかも
  • 個人的にはもう少し流行って欲しいな~
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?