Slide 1

Slide 1 text

αʔόαΠυKotlinͰ GraphQLΛ΍ͬͯΈΑ͏ ͠Β͡

Slide 2

Slide 2 text

Who am I? • Kotlin + GraphQL 1+ year • Open Source kotlin-graphql-sample • Love Kotlin • Works for Ubie, Inc @shiraji @shiraj_i

Slide 3

Slide 3 text

ςΫϊϩδʔͰਓʑΛద੾ͳҩྍʹҊ಺͢Δ

Slide 4

Slide 4 text

Kotlin Fest Organizer & Speakers We are hiring!!! https://ubie.life/

Slide 5

Slide 5 text

͜͜ʹ͍Δਓͨͪ • KotlinΛ৮ͬͨ͜ͱ͕͋Δ • αʔόαΠυKotlinɺGraphQLʹڵຯ͕͋Δ • GET/POST΍ϨεϙϯείʔυͳͲͷHTTPͷجૅతͳ஌͕ࣝ͋Δ • ηογϣϯதʹ൓Ԡͯ͘͠ΕΔ

Slide 6

Slide 6 text

͜͜ʹ͍Δਓͨͪ • KotlinΛ৮ͬͨ͜ͱ͕͋Δ • αʔόαΠυKotlinɺGraphQLʹڵຯ͕͋Δ • GET/POST΍ϨεϙϯείʔυͳͲͷHTTPͷجૅతͳ஌͕ࣝ͋Δ • ηογϣϯதʹ൓Ԡͯ͘͠ΕΔ

Slide 7

Slide 7 text

࣭ͬͦ͘͞໰ αʔόαΠυKotlin΍ͬͨ͜ͱ͋Δਓʔʁ

Slide 8

Slide 8 text

࣭໰2 αʔόαΠυKotlin+GraphQL΍ͬͨ͜ͱ͋Δਓʔʁ

Slide 9

Slide 9 text

࿩͢͜ͱ • GraphQLͱ͸Կʁ • Kotlin+GraphQLͷίʔυͷྲྀΕ • Kotlin+GraphQLͷςετ • Kotlin+GraphQLͷೝূ • Kotlin+GraphQLͷपลπʔϧ

Slide 10

Slide 10 text

࿩͢͜ͱ • GraphQLͱ͸Կʁ • Kotlin+GraphQLͷίʔυͷྲྀΕ • Kotlin+GraphQLͷςετ • Kotlin+GraphQLͷೝূ • Kotlin+GraphQLͷपลπʔϧ

Slide 11

Slide 11 text

ɾɾɾͷલʹɺ͜Μͳܦݧ͋Γ·ͤΜ͔ʁ Ϣʔβͷ໊લҰཡͷAPI͕ཉ͍͠

Slide 12

Slide 12 text

ɾɾɾͷલʹɺ͜Μͳܦݧ͋Γ·ͤΜ͔ʁ { [ "name": “Nagasawa Taro” ], [ "name": “Isogai Yoshinori” ] }

Slide 13

Slide 13 text

ɾɾɾͷલʹɺ͜Μͳܦݧ͋Γ·ͤΜ͔ʁ ͜ͷOSͰ͸first name͚ͩཉ͍͠

Slide 14

Slide 14 text

ɾɾɾͷલʹɺ͜Μͳܦݧ͋Γ·ͤΜ͔ʁ { [ “first_name”: “Taro” ], [ “first_name": “Yoshinori” ] }

Slide 15

Slide 15 text

ɾɾɾͷલʹɺ͜Μͳܦݧ͋Γ·ͤΜ͔ʁ ͜ͷαΠτ͸ TwitterΞΧ΢ϯτ͕ཉ͍͠

Slide 16

Slide 16 text

ɾɾɾͷલʹɺ͜Μͳܦݧ͋Γ·ͤΜ͔ʁ { [ “twitter”: “ngsw_taro” ], [ “twitter": “shiraji” ] }

Slide 17

Slide 17 text

ɾɾɾͷલʹɺ͜Μͳܦݧ͋Γ·ͤΜ͔ʁ ͜ͷAPI͸icon͚ͩͰྑ͍

Slide 18

Slide 18 text

ɾɾɾͷલʹɺ͜Μͳܦݧ͋Γ·ͤΜ͔ʁ { [ “icon”: “https://…” ], [ “icon”: “https://…” ] }

Slide 19

Slide 19 text

ɾɾɾͷલʹɺ͜Μͳܦݧ͋Γ·ͤΜ͔ʁ { [ "name": “Nagasawa Taro”, “first_name”: “Taro”, “twitter”: “ngsw_taro”, “icon”: “https://…” ] }

Slide 20

Slide 20 text

GraphQLͱ͸Կʁ • A query language for your API • εΩʔϚͱΫΤϦ • GraphQL Fundation • OSS • e.g. GitHub API v4

Slide 21

Slide 21 text

εΩʔϚͱΫΤϦ type User { id: ID! name: String! account: String }

Slide 22

Slide 22 text

εΩʔϚͱΫΤϦ type Query { user(id: ID!) : User } type Mutation { createUser(name: String!) } type User { id: ID! name: String! account: String }

Slide 23

Slide 23 text

εΩʔϚͱΫΤϦ query { user(id: "aaa") { id name account } }

Slide 24

Slide 24 text

εΩʔϚͱΫΤϦ type Query { user(id: ID!) : User } type User { id: ID! name: String! account: String }

Slide 25

Slide 25 text

εΩʔϚͱΫΤϦ type Query { user(id: ID! ) a : User } type User {a id: ID! name: String! account: String }a

Slide 26

Slide 26 text

εΩʔϚͱΫΤϦ query { user(id: "aaa" ) a {a id name account }a }

Slide 27

Slide 27 text

εΩʔϚͱΫΤϦ { "data" : {a "id": "aaa", "name": "ү֋Ղయ", "account": "shiraji" }a }

Slide 28

Slide 28 text

εΩʔϚͱΫΤϦ query { user(id: "aaa") {ccc id name account }a }b

Slide 29

Slide 29 text

εΩʔϚͱΫΤϦ query { user(id: "aaa") {ccc id name }a }b

Slide 30

Slide 30 text

εΩʔϚͱΫΤϦ { "data" : {ccc "id": "aaa", "name": "ү֋Ղయ" }a }b

Slide 31

Slide 31 text

εΩʔϚ type Query { users: [User!]! } type User { id: ID! name: String! first_name: String! twitter: String! icon: String! }

Slide 32

Slide 32 text

ΫΤϦ query user() { name } query user() { first_name } query user() { twitter } query user() { Id } query user() { Icon }

Slide 33

Slide 33 text

Ͳ͏͍͏ͱ͜ΖͰ࢖͏ͱྑ͍͔ʁ • FE/BEෳ਺ਓ͕։ൃΛ୲౰ • ϦϞʔτͳͲର໘ରԠ͕Ͱ͖ͳ͍ • ରԠ͢ΔλΠϛϯάʹ͕࣌ࠩ͋Δ

Slide 34

Slide 34 text

ࣄྫ Ubie, Inc

Slide 35

Slide 35 text

ࣄྫ Ubie, Inc

Slide 36

Slide 36 text

࿩͢͜ͱ • GraphQLͱ͸Կʁ • Kotlin+GraphQLͷίʔυͷྲྀΕ • Kotlin+GraphQLͷςετ • Kotlin+GraphQLͷೝূ • Kotlin+GraphQLͷपลπʔϧ

Slide 37

Slide 37 text

kotlin-graphql-sample dependencies { implementation("org.springframework.boot:spring-boot-starter") implementation("com.graphql-java-kickstart:graphql-spring-boot-starter") implementation("com.graphql-java-kickstart:graphiql-spring-boot-starter") implementation(“com.graphql-java-kickstart:graphql-java-tools") implementation("org.springframework.boot:spring-boot-starter-jdbc") }

Slide 38

Slide 38 text

εΩʔϚ type Drug { id: String! name: String! yjCode: String! description: String } type Disease { icd: String! name: String! }

Slide 39

Slide 39 text

εΩʔϚ data class Drug( val id: String, val name: String, val yjCode: String, val description: String? ) data class Disease( val icd: String, val name: String )

Slide 40

Slide 40 text

Query type Query { drug(id: String!) : Drug drugs(yjCode: String!) : [Drug!]! diseases(icd: String!) : [Disease!]! }

Slide 41

Slide 41 text

GraphQLQueryResolver • GraphQLQueryResolverΛܧঝ • ΞϓϦέʔγϣϯ಺ͷ͢΂ͯͷܧঝͨ͠ΫϥεΛࢀর • ϝιου໊ɺҾ਺ɺ໭Γ஋ͰϚοϐϯά • ϝιου໊͸getterͰ΋OK

Slide 42

Slide 42 text

εΩʔϚ type Query {a drugs(yjCode: String!) : [ Drug !]! }a

Slide 43

Slide 43 text

εΩʔϚ @Component class DrugQueryResolver : GraphQL Query Resolver {a fun drugs(yjCode: String ! ) : List< Drug > = TODO() }a

Slide 44

Slide 44 text

εΩʔϚ @Component class DrugQueryResolver : GraphQL Query Resolver { fun drugs(yjCode: String ! ) : List< Drug > = TODO() }

Slide 45

Slide 45 text

Query type Query { drug(id: String! ) a : a Drug drugs(yjCode: String! ) a : a [Drug!]! diseases(icd: String! ) a : a [Disease!]! }

Slide 46

Slide 46 text

Query @Component class DrugQueryResolver : GraphQLQueryResolver { fun drug(id: String ) a : a Drug? = TODO() fun drugs(yjCode: String ) a : a List< Drug > = TODO() } @Component class DiseaseQueryResolver : GraphQLQueryResolver { fun diseases(icd: String ) a : a List< Disease > = TODO() }

Slide 47

Slide 47 text

Request

Slide 48

Slide 48 text

Response

Slide 49

Slide 49 text

෮श • εΩʔϚ͕ॏཁ • type͕͋Δ • KotlinͰ͸data classͰදݱͰ͖Δ • type Query(ͱMutation)͕ಛघ • GraphQLQueryResolverͷϝιουʹ Ϛοϐϯά͞ΕΔ type Drug { id: ID! name: String! description: String } type Query { drugs(code: String) : [Drug]! }

Slide 50

Slide 50 text

෮श໰୊ type User { name: String } data class User( val name: String ) data class User( val name: String? ) data class User( val name: List )

Slide 51

Slide 51 text

͜͜ʹ͍Δਓͨͪ • KotlinΛ৮ͬͨ͜ͱ͕͋Δ • αʔόαΠυKotlinɺGraphQLʹڵຯ͕͋Δ • GET/POST΍ϨεϙϯείʔυͳͲͷHTTPͷجૅతͳ஌͕ࣝ͋Δ • ηογϣϯதʹ൓Ԡͯ͘͠ΕΔ

Slide 52

Slide 52 text

෮श໰୊ type User { name: String } data class User( val name: String ) data class User( val name: String? ) data class User( val name: List )

Slide 53

Slide 53 text

typeͷؔ܎

Slide 54

Slide 54 text

typeͷؔ܎ type Drug { id: ID! name: String! yjCode: String! description: String kinkiDiseases: [Disease!]! } type Disease { icd: String! name: String! kinkiDrugs: [Drug!]! } data class Drug( val id: String, val name: String, val yjCode: String, val description: String? ) data class Disease( val icd: String, val name: String )

Slide 55

Slide 55 text

GraphQLResolver • GraphQLResolverΛܧঝ • ܕม਺͕ϝιουͷҾ਺ • ͋ͱ͸GraphQLQueryResolverͱಉ͡

Slide 56

Slide 56 text

typeͷؔ܎ type Drug { … kinkiDiseases: [Disease!]! } Drug

Slide 57

Slide 57 text

typeͷؔ܎ class DrugResolver : GraphQLResolver< Drug > { fun kinkiDiseases (drug: Drug): List< Disease > { TODO() } }

Slide 58

Slide 58 text

Kotlinݺͼग़͞ΕΔॱ൪

Slide 59

Slide 59 text

Kotlinݺͼग़͞ΕΔॱ൪

Slide 60

Slide 60 text

Kotlinݺͼग़͞ΕΔॱ൪

Slide 61

Slide 61 text

type Drug { id: ID! name: String! yjCode: String! description: String kinkiDiseases: [Disease!]! } data class Drug( val id: String, val name: String, val yjCode: String, val description: String? ) εΩʔϚͱKotlinͷϚοϐϯά·ͱΊ

Slide 62

Slide 62 text

type Drug { id: ID! name: String! yjCode: String! description: String kinkiDiseases: [Disease!]! } class DrugResolver : GraphQLResolver { fun kinkiDiseases(drug: Drug): List {…} } εΩʔϚͱKotlinͷϚοϐϯά·ͱΊ

Slide 63

Slide 63 text

type Drug { id: ID! name: String! yjCode: String! description: String kinkiDiseases: [Disease!]! } data class Drug( val id: String, val name: String, val yjCode: String, val description: String? ) class DrugResolver : GraphQLResolver { fun kinkiDiseases(drug: Drug): List {…} } εΩʔϚͱKotlinͷϚοϐϯά·ͱΊ

Slide 64

Slide 64 text

࿩͢͜ͱ • GraphQLͱ͸Կʁ • Kotlin+GraphQLͷίʔυͷྲྀΕ • Kotlin+GraphQLͷςετ • Kotlin+GraphQLͷೝূ • Kotlin+GraphQLͷपลπʔϧ

Slide 65

Slide 65 text

• mock͢Ε͹OK Kotlin+GraphQLͷςετ Ҏ্ɻ

Slide 66

Slide 66 text

࿩͢͜ͱ • GraphQLͱ͸Կʁ • Kotlin+GraphQLͷίʔυͷྲྀΕ • Kotlin+GraphQLͷςετ • Kotlin+GraphQLͷೝূ • Kotlin+GraphQLͷपลπʔϧ

Slide 67

Slide 67 text

Kotlin+GraphQLͷೝূ • ೝূํ๏͸͍͔ͭ͋͘Δ • Auth HeaderͷtokenͰೝূ͢Δํ๏Λ঺հ • Authorization: Bearer

Slide 68

Slide 68 text

DataFetchingEnvironment • ֤छResolver͔ΒΞΫηεՄೳ • Fetch͢΂͖৘ใ • ϑΟʔϧυͷҾ਺ • ϑΟʔϧυͷ਌ͷ৘ใ

Slide 69

Slide 69 text

DataFetchingEnvironment @Component class DrugQueryResolver : GraphQLQueryResolver { fun drug(id: String): Drug? { TODO() }a }a

Slide 70

Slide 70 text

DataFetchingEnvironment @Component class DrugQueryResolver : GraphQLQueryResolver { fun drug( id: String, environment: DataFetchingEnvironment): Drug? { TODO() }a }a

Slide 71

Slide 71 text

DataFetchingEnvironment @Component class DrugQueryResolver : GraphQLQueryResolver { fun drug( environment: DataFetchingEnvironment, id: String): Drug? { TODO() }a }a ເͷ࿩Ͱ͢

Slide 72

Slide 72 text

DataFetchingEnvironment @Component class DrugQueryResolver : GraphQLQueryResolver { fun DataFetchingEnvironment. drug( id: String): Drug? { TODO() }a }a ເͷ࿩Ͱ͢

Slide 73

Slide 73 text

Context • DataFetchingEnvironment͔ΒContextʹΞΫηεͰ͖Δ • ΫΤϦड͚औΓʙऴΘΓ·Ͱੜ͖Δ • ͲΜͳ஋Ͱ΋OK • GraphQLContextΛܧঝ͢Δ • ެ͕͓ࣜ͢͢Ί

Slide 74

Slide 74 text

Context class AuthContext(httpServletRequest: HttpServletRequest, val userId: Long?) : GraphQLContext(httpServletRequest)

Slide 75

Slide 75 text

GraphQLContextBuilder @Bean fun contextBuilder(): GraphQLContextBuilder { return object : DefaultGraphQLContextBuilder() { }b }a

Slide 76

Slide 76 text

GraphQLContextBuilder @Bean fun contextBuilder(): GraphQLContextBuilder { return object : DefaultGraphQLContextBuilder() { override fun build( httpServletRequest: HttpServletRequest, httpServletResponse: HttpServletResponse ): GraphQLContext { }c }b }a

Slide 77

Slide 77 text

GraphQLContextBuilder @Bean fun contextBuilder(): GraphQLContextBuilder { return object : DefaultGraphQLContextBuilder() { override fun build( httpServletRequest: HttpServletRequest, httpServletResponse: HttpServletResponse ): GraphQLContext { val authHeader = httpServletRequest.getHeader(“Authorization") }c }b }a

Slide 78

Slide 78 text

GraphQLContextBuilder @Bean fun contextBuilder(): GraphQLContextBuilder { return object : DefaultGraphQLContextBuilder() { override fun build( httpServletRequest: HttpServletRequest, httpServletResponse: HttpServletResponse ): GraphQLContext { val authHeader = httpServletRequest.getHeader("Authorization") val token = authHeader?.removePrefix("Bearer ") val userId = TODO() // ͳΜͱ͔͢Δ }c }b }a

Slide 79

Slide 79 text

GraphQLContextBuilder @Bean fun contextBuilder(): GraphQLContextBuilder { return object : DefaultGraphQLContextBuilder() { override fun build( httpServletRequest: HttpServletRequest, httpServletResponse: HttpServletResponse ): GraphQLContext { val authHeader = httpServletRequest.getHeader("Authorization") val token = authHeader?.removePrefix("Bearer ") val userId = TODO() return AuthContext(httpServletRequest, userId) }c }b }a

Slide 80

Slide 80 text

DataFetchingEnvironment @Component class DrugQueryResolver : GraphQLQueryResolver { fun drug(id: String, environment: DataFetchingEnvironment): Drug? { TODO(“DrugΛऔಘ͢Δॲཧ”) }b }a

Slide 81

Slide 81 text

DataFetchingEnvironment @Component class DrugQueryResolver : GraphQLQueryResolver { fun drug(id: String, environment: DataFetchingEnvironment): Drug? { environment.getContext().userId ?: throw Exception(“ೝূ͞Εͯͳ͍Α”) TODO(“DrugΛऔಘ͢Δॲཧ”) }b }a

Slide 82

Slide 82 text

Kotlin + GraphQLೝূ·ͱΊ • DataFetchingEnvironment͸֤छResolverͰΞΫηεՄೳ • ಠࣗͷContextΛ࡞੒Մೳ • GraphQLContextΛܧঝ͢Δ • Context͸GraphQLContextBuilder#build಺Ͱੜ੒ • Contextʹೝূ৘ใ࣋ͨͤͯResolver಺Ͱೝূ͢Δ

Slide 83

Slide 83 text

࿩͢͜ͱ • GraphQLͱ͸Կʁ • Kotlin+GraphQLͷίʔυͷྲྀΕ • Kotlin+GraphQLͷςετ • Kotlin+GraphQLͷೝূ • Kotlin+GraphQLͷपลπʔϧ

Slide 84

Slide 84 text

GraphiQL • ϒϥ΢βΛGraphQLͷΫΤϦฤूIDEʹ • dependenciesʹॻ͚͹ɺαʔό্ཱͪ͛Ε͹ಈ͘ʂ dependencies { implementation("com.graphql-java-kickstart:graphiql-spring-boot-starter") }

Slide 85

Slide 85 text

σϞ

Slide 86

Slide 86 text

Altair • GraphiQLͱ΄΅ಉ͡ • HeaderͷઃఆΛϒϥ΢β্Ͱ؆୯ʹग़དྷΔ dependencies { implementation("com.graphql-java-kickstart:altair-spring-boot-starter") }

Slide 87

Slide 87 text

apollo-android • GraphQLΛ࢖͏ଆ • Androidͱॻ͔Ε͍ͯΔ͚ͲɺJavaϕʔεͰར༻Մೳ

Slide 88

Slide 88 text

͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠