1.gradle相关信息
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("org.springframework.boot") version "2.5.6" id("io.spring.dependency-management") version "1.0.11.RELEASE" kotlin("jvm") version "1.6.21" kotlin("plugin.spring") version "1.6.21" id("com.netflix.dgs.codegen") version "5.1.16" } group = "com.ityu" version = "0.0.1-SNAPSHOT" java.sourceCompatibility = JavaVersion.VERSION_11 configurations { compileOnly { extendsFrom(configurations.annotationProcessor.get()) } } repositories { mavenCentral() } dependencies { implementation("org.springframework.boot:spring-boot-starter-web") implementation("com.fasterxml.jackson.module:jackson-module-kotlin") implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") implementation(platform("com.netflix.graphql.dgs:graphql-dgs-platform-dependencies:latest.release")) implementation ("com.netflix.graphql.dgs:graphql-dgs-spring-boot-starter") implementation("com.netflix.graphql.dgs:graphql-dgs-extended-scalars") implementation("com.github.javafaker:javafaker:1.+") implementation ("org.springframework.boot:spring-boot-starter-test") developmentOnly("org.springframework.boot:spring-boot-devtools") annotationProcessor("org.springframework.boot:spring-boot-configuration-processor") testImplementation("org.springframework.boot:spring-boot-starter-test") } tasks.withType<KotlinCompile> { kotlinOptions { freeCompilerArgs = listOf("-Xjsr305=strict") jvmTarget = "11" } } // tasks.withType<com.netflix.graphql.dgs.codegen.gradle.GenerateJavaTask> { generateClient = true packageName = "com.ityu.demo.generated" } tasks.withType<Test> { useJUnitPlatform() }
2. 添加resources/schema/schema.graphql
type Query { #方法返回数组 events:[Event!]! } type Mutation { createEvent(eventInput:EventInput!):Event! } input EventInput{ title:String! description:String! price:String! data:String! } type Event{ id:ID! title:String! description:String! price:String! data:String! }
3. java代码
@DgsComponent class EventDataFetcher { private val events = mutableListOf<Event>() @DgsQuery fun events(): MutableList<Event> { return events } @DgsMutation fun createEvent(@InputArgument eventInput: EventInput): Event { val event = Event( UUID.randomUUID().toString(), eventInput.title, eventInput.description, eventInput.price, eventInput.data ) events.add(event) return event } }
4.打开浏览器工具
mutation{ createEvent(eventInput:{ title:"title2", description:"description 2", price:"50.99", data:"2222", }){ id description price data } } # 添加对象 query{ events{ id title } }
5. OKhttp调用
fun testGraphql() { //query val apply = getObjectNode().apply { put( "query", """query{ uses{ id } }""" ) } //mutation val apply2 = getObjectNode().apply { put( "query", """mutation{ createUser(userInput:{ email:"test@test4", password:"testest3" }){ id password } }""" ) } //带参数 val apply3 = getObjectNode().apply { put( "query", """mutation cU(${'$'}email:String!,${'$'}password:String!){ createUser(userInput:{ email:${'$'}email, password:${'$'}password }){ id password } }""").put("variables", getObjectNode().put("email","3@3.com").put("password","99999")) } val toRequestBody = apply3.toString().toRequestBody("application/json; charset=utf-8".toMediaType()) val post = Request.Builder().url("http://localhost:8081/graphql").post(toRequestBody).build() val client = getOkHttpClient().newCall(post).execute() //0x0000000000000000000000000000000000000000 println(client.body?.string() ?: "====") }
6. doctor compose up
需要在有docker-compose.yml文件的文件夹下执行该命令
7. DgsCustomContextBuilderWithRequest
DgsContext.getCustomContext(DgsDataFetchingEnvironment)
@Component @Slf4j class AuthContextBuilder(var userDataFetcher:UserDataFetcher) : DgsCustomContextBuilderWithRequest<AuthContext?> { override fun build(extensions: Map<String, Any>?, headers: HttpHeaders?, webRequest: WebRequest?): AuthContext? { headers?.let { log.warn("AuthContextBuilder${it.getFirst("a_h")}") return AuthContext(userDataFetcher.uses().find { it.id=="1" },false) } return null } }
8. Resolver 使用
parentType 那个TYPE field 那个属性
对Event的两个属性赋值
//schema.graphql中定义 type Event{ user:User! events:[Event!] } @DgsData(parentType = "Event", field="user") fun creator(dfe:DgsDataFetchingEnvironment): User? { val event = dfe.getSource<Event>() val id = event.creatorId return usersData.find { it.id == id.toString() } } @DgsData(parentType = "User", field = "events") fun events(dfe: DgsDataFetchingEnvironment): MutableList<Event>? { val user = dfe.getSource<User>() val events = eventsData.filter { it.creatorId.toString() == user.id } return events.toMutableList() }
9. 查询相关
参数human(id:“1000”)
height(unit:FOOT) 设置返回值类型为float
别名写法 别名:原名 a:hero b:hero
定义fragment xxx on yyy 就是在yyy上面选择一些字段 使用…xxx
query name{} 定义一个名字
… on yyy{}
implements interface
__typename
query variables
request headers
使用变量 query name($filedName:filedType){xxx(fileName:$filedName)}
mutation cU($email:String!,$password:String!){ createUser(userInput:{ email:$email, password:$password }){ id password } } { "email": "testemail2", "password": "fdsafdasf" } // fragment fragment A on Booking{ id event{ id } } //interface implements interface B { id: ID! event: Event! } type Bb implements B{ id: ID! event: Event! }
10. DataLoder
//创建DataLoader @DgsDataLoader(name = "creators") class CreatorsDataLoader:BatchLoader<Int, User> { override fun load(userIds: MutableList<Int>): CompletionStage<MutableList<User>> { return CompletableFuture.supplyAsync{ return@supplyAsync usersData.filter { userIds.contains(it.id.toInt()) }.toMutableList() } } } //使用 该方法还是会调用多次,只不过不会从数据库取数据 //组合成一起批量获取 @DgsData(parentType = "Event", field="user") fun creator(dfe:DgsDataFetchingEnvironment): CompletableFuture<User> { val event = dfe.getSource<Event>() val id = event.creatorId val dataLoader = dfe.getDataLoader<Int,User>(CreatorsDataLoader::class.java) return dataLoader.load(id) }