am414
01/17/2021, 10:18 AMRobert
01/30/2021, 1:44 PM> Could not resolve all files for configuration ':compileClasspath'.
> Could not find com.apollographql.federation:federation-graphql-java-support:0.5.0.
Required by:
project : > com.expediagroup:graphql-kotlin-spring-server:3.7.0
project : > com.expediagroup:graphql-kotlin-spring-server:3.7.0 > com.expediagroup:graphql-kotlin-federation:3.7.0
András Hatvani
02/08/2021, 8:21 AMMarcus Dunn
02/08/2021, 11:24 PMFetchType.LAZY
to a schema-exposed class? If I pass a entity to the constructor then just call the field inside the function (example below) I'll receive an error because the session is closed by the time the function is called.
I have this entity class
@Entity
class Foo(
@Id
val id: Long
@OneToOne(fetch = FetchType.LAZY)
var bar: Bar
)
this class here is the one exposed to the schema, its mapped almost 1-1 with the Foo
class, but with the potential to have more fields I don't necessarily want in the Foo
entity.
class GraphQlFoo(private val entity: Foo) {
val id = entity.id
fun bar() = GraphQLBar(entity.bar)
}
This setup breaks at the moment, Ideally I'd like some way to fetch bar
if and only if it was requested, and not have to do unessisary joins if it the request doesn't include it. I'd also like to do all this logic in a single session, as opening a second to just fetch bar
seems unneeded which is what my current solution does via fun bar(@GraphQLIgnore @Autowired barRepository: BarRepository) = barRepository.getByFooId(id)
mytrile
02/09/2021, 5:44 PMorg.springframework.beans.factory.BeanCreationException: Error creating bean with name 'webHandler' defined in class path resource [org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfiguration$EnableWebFluxConfiguration.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'routerFunctionMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfiguration$EnableWebFluxConfiguration.class]: Invocation of init method failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.expediagroup.graphql.spring.RoutesConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.expediagroup.graphql.spring.GraphQLConfigurationProperties' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
hisham bin awiad
02/13/2021, 2:50 PMandroid side
, any recommended resource for start with it . i hope to find any resource with Retrofit
plz share any resource with meTianyu Zhan
02/15/2021, 4:46 PMgradle clean build
dave08
02/17/2021, 9:15 AMAnders Kirkeby
02/17/2021, 3:08 PMdave08
02/18/2021, 12:59 PMdave08
02/18/2021, 4:23 PMdave08
02/21/2021, 12:28 PMdave08
02/22/2021, 3:55 PMJeremy Beard
02/22/2021, 4:25 PMDaniel Skogquist Åborg
02/28/2021, 11:45 AMTianyu Zhan
03/01/2021, 10:31 PMdave08
03/07/2021, 12:45 PMDas135
03/10/2021, 12:37 PMEnum
that as got name
property.
I have got Graphql server that has got enum class properties defined in UPPERCASE and renamed with @GraphQLName
(because of name
property).
enum class EnumClass {
@GraphQLName("id")
@JsonProperty("id")
ID,
@GraphQLName("name")
@JsonProperty("name")
NAME,
@GraphQLName("createdAt")
@JsonProperty("createdAt")
CREATED_AT,
@GraphQLName("createdById")
@JsonProperty("createdById")
CREATED_BY_ID,
}
Now I want to use this type in my graphql-kotlin-client, but generator creates this class:
enum class EnumClass {
createdAt,
createdById,
id,
name,
/**
* This is a default enum value that will be used when attempting to deserialize unknown value.
*/
@JsonEnumDefaultValue
__UNKNOWN_VALUE
}
There is a problem that Kotlin Enum cannot has got a name
property.
Please, it is possible to somehow solve it? Thank youNikky
03/15/2021, 10:49 AMRobert
03/20/2021, 7:40 AMimport com.expediagroup.graphql.annotations.GraphQLDescription
import com.expediagroup.graphql.spring.operations.Query
import org.springframework.stereotype.Component
@Component
interface QueryB : Query, SubQuery {
@GraphQLDescription("Get B")
suspend fun queryB(): B
// corresponds to the field name in parent model (e.g. A.b)
override val fieldName: String
get() = "b"
}
@Component
interface QueryA : Query {
@GraphQLDescription("Get A")
suspend fun queryA(): A
}
data class A(
val aValue: String,
val b: B? // corresponds with field name
)
data class B(
val bValue: String,
)
interface SubQuery {
/**
* Name when used in parent model
*/
val fieldName: String
}
To implement the resolver for A (including B) it's needed to:
• Inject resolver for B into A
• Execute some custom logic to see if the query for A also requested field B
This kina works, but is a bit cumbersome and works against the benefits of graphql magic resolving what is needed:
class QueryAImpl(private val queryB: QueryB) : QueryA {
override suspend fun queryA(): A {
val aValue = A("A")
val `was b requested as part of a?` = true
return if (`was b requested as part of a?`) {
aValue.copy(b = queryB.queryB())
} else aValue
}
}
I think the DataLoader approach could help here, or?
https://github.com/ExpediaGroup/graphql-kotlin/blob/master/examples/server/spring-[…]graphql/examples/server/spring/dataloaders/CompanyDataLoader.ktRobert
03/20/2021, 10:13 AM@GraphQLDescription("performs some operation")
fun doSomething(
@GraphQLDescription("super important value")
value: Int?
): Boolean = true
this works ✅
query {
doSomething(value:null) {
..
}
}
this fails in 4.0.0-alpha.15 ❗ : no argument provided for a required parameter: parameter #1 query of fun SomeQuery.doSomething(<http://kotlin.Int?|kotlin.Int?>)
and works with 3.7.0
query {
doSomething {
..
}
}
it works again when using a default
@GraphQLDescription("performs some operation")
fun doSomething(
@GraphQLDescription("super important value")
value: Int? = null
): Boolean = true
Jabez Magomere
03/23/2021, 11:07 AMimport com.androidmaestro.users.data.repository.UserRepository
import com.androidmaestro.users.domain.entity.UserEntity
import com.expediagroup.graphql.types.operations.Query
import graphql.relay.*
class UsersQuery(private val repository: UserRepository) : Query{
suspend fun users(first:Int, cursor : String?) : UsersConnection = repository.getAll(first, cursor)
}
class UsersConnection(users:List<Edge<UserEntity>>, userPageInfo : DefaultPageInfo) : DefaultConnection<UserEntity>(users, userPageInfo)
However the schema generation fails with the error shown below.
Caused by: java.lang.IllegalArgumentException: Class declares 1 type parameters, but 0 were provided.
at kotlin.reflect.full.KClassifiers.createType(KClassifiers.kt:53)
at kotlin.reflect.full.KClassifiers.createType$default(KClassifiers.kt:45)
at com.expediagroup.graphql.generator.internal.types.GenerateObjectKt.generateObject(generateObject.kt:46)
at com.expediagroup.graphql.generator.internal.types.GenerateGraphQLTypeKt.getGraphQLType(generateGraphQLType.kt:74)
at com.expediagroup.graphql.generator.internal.types.GenerateGraphQLTypeKt.access$getGraphQLType(generateGraphQLType.kt:1)
at com.expediagroup.graphql.generator.internal.types.GenerateGraphQLTypeKt$objectFromReflection$1.invoke(generateGraphQLType.kt:63)
at com.expediagroup.graphql.generator.internal.types.GenerateGraphQLTypeKt$objectFromReflection$1.invoke(generateGraphQLType.kt)
at com.expediagroup.graphql.generator.internal.state.TypesCache.buildIfNotUnderConstruction$graphql_kotlin_schema_generator(TypesCache.kt:108)
at com.expediagroup.graphql.generator.internal.types.GenerateGraphQLTypeKt.objectFromReflection(generateGraphQLType.kt:62)
at com.expediagroup.graphql.generator.internal.types.GenerateGraphQLTypeKt.generateGraphQLType(generateGraphQLType.kt:40)
at com.expediagroup.graphql.generator.internal.types.GenerateGraphQLTypeKt.generateGraphQLType$default(generateGraphQLType.kt:36)
at com.expediagroup.graphql.generator.internal.types.GenerateFunctionKt.generateFunction(generateFunction.kt:54)
at com.expediagroup.graphql.generator.internal.types.GenerateFunctionKt.generateFunction$default(generateFunction.kt:33)
at com.expediagroup.graphql.generator.internal.types.GenerateQueryKt.generateQueries(generateQuery.kt:43)
at com.expediagroup.graphql.generator.SchemaGenerator.generateSchema(SchemaGenerator.kt:80)
at com.expediagroup.graphql.generator.SchemaGenerator.generateSchema$default(SchemaGenerator.kt:73)
at com.expediagroup.graphql.generator.ToSchemaKt.toSchema(toSchema.kt:41)
at com.expediagroup.graphql.generator.ToSchemaKt.toSchema$default(toSchema.kt:37)
at com.androidmaestro.graphql.Schema.<clinit>(Schema.kt:51)
... 76 common frames omitted
2021-03-23 14:01:21.087 [eventLoopGroupProxy-4-1] ERROR Application - Unhandled exception
java.lang.NoClassDefFoundError: Could not initialize class com.androidmaestro.graphql.Schema
Brian Dilley
03/25/2021, 8:49 PMdata class Movie(
val id: Long,
val token: String
)
data class User(
val id: Long,
val name: String
) {
fun movies(userIds: List<Long>): List<Movie> {
return LongRange(0, 2)
.map { Movie(it, "movie-$it") }
.toList()
}
}
@Component
class UserQueries : Query {
fun users(): List<User> {
return LongRange(0, 5)
.map { User(it, "user-$it") }
.toList()
}
}
In a database situation it would be really bad to query users along with their movies because it would issue a single query per user to get their movies. Is there a way to avoid the multiple queries and instead get a list of the user ids and make a single query for all of their movies?Brian Dilley
03/26/2021, 6:46 AM@Secured
and it throws an exception (AuthenticationCredentialsNotFoundException
) when expected, but how do i define an “error resolver” that can take that exception and turn it into a more meaningful message (ie: right now it’s An Authentication object was not found in the SecurityContext
for that exception, i’d rather say something like Access Denied
)Marcus Dunn
03/29/2021, 6:15 PMclass java.util.LinkedHashMap cannot be cast to class com.expediagroup.graphql.examples.server.spring.query.ScalarQuery$PhoneNumber
fun convolutedExample(optListInput: OptionalInput<List<PhoneNumber>>): String {
return patient
.let { if (it is OptionalInput.Defined) it.value else null }
?.map { it.number }
.toString()
}
data class PhoneNumber(val number: Long)
when called like this
@Test
fun test() {
val query = "convolutedExample"
val expectedData = "[111111]"
<http://testClient.post|testClient.post>()
.uri(GRAPHQL_ENDPOINT)
.accept(APPLICATION_JSON)
.contentType(GRAPHQL_MEDIA_TYPE)
.bodyValue("""query { $query(optListInput: [{
| number: 111111,
| }]
|) }""".trimMargin())
.exchange()
.verifyData(query, expectedData)
}
Have I gone wrong somewhere or is this just too many generics deep for jackson to figure out?Dariusz Kuc
04/07/2021, 7:08 PM4.0.0-rc.1
would greatly appreciate it if you could try it out and report any issues.Joe
04/07/2021, 10:44 PMPublisher
now instead of a Flow
. This makes sense for spring webflux, but we're consuming `Flow`s directly and the Flow
->`Publisher`->`Flow` round trip has caused resource leak problems for us in the past. Would something like a NativeFlowSubscriptionExecutionStrategy
that returns `Flow`s be welcome in graphql-kotlin
or should we maintain it externally?
2. instrumentation doesn't appear to be applied to subscription results. Previously fixed in https://github.com/ExpediaGroup/graphql-kotlin/pull/742 but maybe in going to Publisher
lost that? (or maybe something's changed in graphql-java 16 around it?)
other than that, updating package import definitions and some renames in graphql-java 16 (ExecutionPath -> ResultPath) appear to be the main changes that we need to adjust for. There's also some weirdness with the selectionSet duplicating fields that appears to be filed upstream as https://github.com/graphql-java/graphql-java/issues/2275.Jilles van Gurp
04/08/2021, 2:04 PM@Component
to the example for custom scalars. Without that, it doesn't work for obvious reasons.
• The documentation suggests this should only work with things like strings, which seems to be not the case
• Maybe generalize the approach below to have kotlinx.serialization and maybe jackson strategies for coercion. Mostly that should work and users can simply reuse their existing serialization/deserialization logic that way. Or if that is supported some other way, maybe document that?
@Component
class GeometryGraphqlScalar : SchemaGeneratorHooks {
override fun willGenerateGraphQLType(type: KType): GraphQLType? {
return when (type.classifier as? KClass<*>) {
Geometry::class -> geometryScalar
else -> null
}
}
}
private val geometryScalar = GraphQLScalarType
.newScalar()
.name("Geometry")
.description("json serialized geometry")
.coercing(GeometryCoercing)
.build()
object GeometryCoercing : Coercing<Geometry, Geometry?> {
override fun serialize(input: Any): Geometry {
// little hack, causes toString to be called, which we implemented using Json.encodeToString ...
return input as Geometry
}
override fun parseValue(input: Any): Geometry {
error("we don't support parameter scalars currently but we could ${input::class.qualifiedName}")
}
override fun parseLiteral(input: Any): Geometry {
error("we don't support parameter scalars currently but we could ${input::class.qualifiedName}")
}
}
Dariusz Kuc
04/20/2021, 2:15 PMandylamax
04/25/2021, 10:22 AM