Share
Embed
Transcript
30 slides
-
もくじ 1. なぜKotlinなのか 2. Spring Boot いいかんじ 3. Spring Boot
あれこれ 4. GraphQL 少しだけ使ってる -
1. なぜKotlinなのか 2. Spring Boot いいかんじ 3. Spring Boot あれこれ
4. GraphQL 少しだけ使ってる -
いまやJava 15, 16 • KotlinとJavaの文法における差が縮まってきた • それでもKotlinにしかないもの ◦ 名前付き引数 ◦
拡張関数 ◦ suspend関数 ◦ プロパティ ◦ null安全 ◦ 型エイリアス (etc…) • Kotlinエコシステムも充実してきた -
UbieでサーバサイドKotlinを導入した経緯 • 2018年、太郎 Ubie入社、6人目の社員 • 当時 Web APIはRuby on Railsアプリ1個だけ
• 新たな機能を追加するにあたってKotlinでWeb APIを開発 • 理由: ◦ 複雑な医療データを扱う上で静的型を欲した ◦ 僕自身、手の馴染む道具だった(Javaの利用経験もあった) • 大原則として、合理で判断。Kotlinにこだわりはない。 -
1. なぜKotlinなのか 2. Spring Boot いいかんじ 3. Spring Boot あれこれ
4. GraphQL 少しだけ使ってる -
KotlinでさくっとHelloWorld @SpringBootApplication class DemoApplication fun main(args: Array<String>) { runApplication<DemoApplication>(*args) }
@Service class HelloWorldService { fun helloWorld(): String = "Hello, world!" } @RestController class HelloWorldController(val helloWorldService: HelloWorldService) { @GetMapping("/hello-world") fun helloWorld(): String = helloWorldService.helloWorld() } -
Kotlinってデフォルトでfinalクラスだよね • Kotlinのクラスはデフォルトでfinalクラス(継承ダメ) • open修飾子で継承を明示的に許可する • @Serviceなどが付いたクラスはSpringによってサブクラスが生 成される(継承を許可する必要がある) plugins {
... kotlin("plugin.spring") version "1.4.21" } プラグインがうまいことやってくれるから 意識する必要ないのです! -
WebFlux: Reactorごりごり使うスタイル @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun
handle(): Mono<String> = Mono.zip( demoService.getMonoA(), demoService.getMonoB() ) .flatMap { demoService.getMonoC(it.t1, it.t2) } .map { it.answer } } -
WebFlux: async/awaitでやってMonoに変換 @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun
handle(): Mono<String> = mono { val a = async { demoService.getItemA() } val b = async { demoService.getItemB() } val c = async { demoService.getItemC(a.await(), b.await()) } c.await().answer } } -
WebFlux: suspend関数で素直に @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") suspend
fun handle(): String { val a = async { demoService.getItemA() } val b = async { demoService.getItemB() } val c = async { demoService.getItemC(a.await(), b.await()) } return c.await().answer } } -
Ktorはどう? • JetBrains公式のWebマイクロフレームワーク ◦ 非常に薄い ◦ DSL、ノンブロッキングなどの特徴 • だからこその苦労はありそう→考えることたくさん ◦
DIどうする…? ◦ DBアクセスは…? ◦ コントローラとか、ファイル分割、アーキテクチャ ◦ やりたいことが明確に決まってるならSpring Bootでよさそう • UbieではPHR基盤プロジェクトでKtor採用を真面目に検討し ていた。が、断念。 -
1. なぜKotlinなのか 2. Spring Boot いいかんじ 3. Spring Boot あれこれ
4. GraphQL 少しだけ使ってる -
バリデーションに注意 class PatientPostBody ( @NotNull val age: Int, @NotBlank val
name: String ) class PatientPostBody ( @field:NotNull val age: Int, @field:NotBlank val name: String ) class PatientPostBody ( @field:NotNull val age: Int?, @field:NotBlank val name: String ) -
Kotlin DSLでBean登録 @SpringBootApplication class DemoApplication fun main(args: Array<String>) { SpringApplicationBuilder()
.sources(DemoApplication::class.java) .initializers(beans { bean { HelloWorldService() } }) .run(*args) } class HelloWorldService { fun helloWorld(): String = "Hello, world!" } -
ルーティングもDSLに! fun main(args: Array<String>) { SpringApplicationBuilder() .sources(DemoApplication::class.java) .initializers(beans { bean
{ HelloWorldService() } bean { HelloWorldController(ref()) } bean { router { GET("/hello-world") { ref<HelloWorldController>().helloWorld() } } } }) .run(*args) -
Ubieコーディングガイドラインのポイント • スタイルはktlintに従う • シンプルに保つ ◦ Kotlinは表現力が高い分、エレガントの極みを目指すと可読性が下がって本末転 倒になるおそれが • テストコードは素直に
◦ テストに必要なものが、一目ですべて手に入る世界がいいな • 型を明記する • !!を使用しない ◦ 代わりにrequireNotNull関数を使用する • lateinitは使用しない ◦ 本来NullableなのにNotNullにしたいがための抜け道 ◦ テストコードの@Autowiredなプロパティにはlateinitを使用 -
1. なぜKotlinなのか 2. Spring Boot いいかんじ 3. Spring Boot あれこれ
4. GraphQL 少しだけ使ってる -
Kotlin x Spring Boot x GraphQL type Query { drugs(yjCode:
String!) : [Drug!] } type Drug { yjCode: String! name: String! } @Component class DrugQueryResolver( val drugService: DrugService ): GraphQLQueryResolver { fun drugs(yjCode: String): List<Drug> { return drugService.getDrugs(yjCode) } } しらじさんによるサンプルコード https://github.com/ubie-inc/kotlin-graphql-sample -
GraphQLやるときの登場人物 • QueryResolver: API、問い合わせの入口に相当 • Resolver: ネストで取得したいリソースを指定したとき • DataLoader: N
+ 1を回避するための遅延ロード機構 フレームワークが提供するインタフェースを実装し @Componentなりを付ける -
1. なぜKotlinなのか 2. Spring Boot いいかんじ 3. Spring Boot あれこれ
4. GraphQL 少しだけ使ってる -
まとめ • KotlinはBetter Javaとして有用 • SpringとKotlinは仲良し!多くの場面で自然に使える • Ktorは薄いがゆえに大変そうか?個人的な見解 • GraphQLもKotlin
x SpringでOK サーバサイドKotlin いいよ!