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()
}
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!
}
@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
}
}
mutation{
createEvent(eventInput:{
title:"title2",
description:"description 2",
price:"50.99",
data:"2222",
}){
id
description
price
data
}
}
# 添加对象
query{
events{
id
title
}
}
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() ?: "====")
}
需要在有docker-compose.yml文件的文件夹下执行该命令
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
}
}
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()
}
参数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!
}
//创建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)
}