Comments (13)
These would be great improvements. Both proposed features need to be thoroughly analyzed in context of KGraphQL's architecture and API. I will come back to you soon with some proposals/conclusions. Thanks!
from kgraphql.
Awesome! While your at it, maybe you can think of a good way to control the introspection. As an example you don't want to give easy access to the graphql schema on a public website. Maybe an interface that normally return "true" (= allow introspection) but which can be overriden?
from kgraphql.
I agree that possibility to limit access to introspection is a must have. I guess it will be introduced with field permission control.
I was prototyping a bit today, trying to implement context
parameter to resolvers. What do you think about following snippet:
data class UserData(val name : String, val isAdmin : Boolean = false)
val contextDemoSchema = KGraphQL.schema {
query("me"){
//Context is class provided by library, it wraps context pairs provided to execute method
resolver { ctx: Context -> ctx.get<UserData>("userData").name }
}
}
fun main(args : Array<String>) {
//fun execute(request: String, vararg context: Pair<String, Any> = emptyArray())
val meName = contextDemoSchema.execute("{me}", "userData" to UserData("Jan Kowalski"))
println(meName) // prints '{"data":{"me":"Jan Kowalski"}}'
}
About permission control - I'm still collecting informations and searching for best approach.
from kgraphql.
That is one way of doing it. Though what I love with your library is how clean and readable the code become. Wrapping stuff in a Context object make the code less readable.
Hmm, maybe if we drop the "Context" definition and see this like a need of being able to pass a custom object to the resolver (some might use it as a Context, others for debugging) and then have an additional resolver that begins with _ (underscore).
// How we do it today
query("me"){
resolver { name : String -> ...... }
}
// Optional way
query("me"){
_resolver { _ : Any, name : String -> ...... }
}
_resolver
always pass the custom object defined as third parameter in execute
as first parameter.
Well something like this to still keep the code clean. Remember that we are trying to solve a problem most likely only used on public websites.
from kgraphql.
I see your point. At glance, your proposal looks more readable and straightforward. On the other hand, client code would have to cast context object to expected type, and in case if it would need multiple context objects(because code calling Schema.execute
shouldn't care what query is executed), custom context class would need to be created. So, effectively it would look like this:
data class UserData(val name : String, val isAdmin : Boolean = false)
data class RequestData(val time: Timestamp)
//just wrapper for context objects
data class Context(val userData: UserData, val requestData : RequestData)
val contextDemoSchema = KGraphQL.schema {
query("me"){
_resolver { _ctx: Any -> (_ctx as Context).userData.name }
}
query("time"){
_resolver{ _ctx : Any -> (_ctx as Context).requestData.timestamp }
}
}
fun main(args : Array<String>) {
val context = Context(UserData("Jan Kowalski"), RequestData(System.currentTimeMillis()))
val meName = contextDemoSchema.execute("{me}", context)
println(meName) // prints '{"data":{"me":"Jan Kowalski"}}'
}
that's why I think that in long run, this solution may be less flexible and a bit inconvenient for bigger codebases.
I'm thinking, maybe we can meet somewhat in the middle, and introduce @Context
annotation, so library would know which arguments it should inject into resolvers so previous example would look like this:
@Context
data class UserData(val name : String, val isAdmin : Boolean = false)
@Context
data class RequestData(val time: Timestamp)
val contextDemoSchema = KGraphQL.schema {
query("me"){
resolver { userData: UserData -> userData.name }
}
query("time"){
resolver{ requestData : RequestData -> requestData.timestamp }
}
}
fun main(args : Array<String>) {
val meName = contextDemoSchema.execute("{me}", UserData("Jan Kowalski"), RequestData(System.currentTimeMillis()))
println(meName) // prints '{"data":{"me":"Jan Kowalski"}}'
}
It would work a little like Spring's injection of controller handlers, but we have to remember that it would introduce big portion of complexity and behind the scenes 'magic'. Another concern is that client code may want to pass instance of class defined by another library/framework, so maybe DSL method like
context<UserData>()
context<RequestData>()
would be convenient as well.
What do you think?
from kgraphql.
Would it be possible to add T2 to the definition of resolver?
resolver<T> { param1 : Int -> ... }
resolver<T1, T2> { ctx (T2), param1 : Int -> .... }
T, T1 = Return Type
T2 = Context Type
I use Spring injection in all my projects and love it, but if you walk that path then you will steer away from the simplicity of your library (which i also love).
from kgraphql.
So to sum up, if we agree on single context type created by client code, maybe it should be generic parameter of Schema
interface? this way, execute
method and resolvers
could be type checked.
data class UserData(val name : String, val isAdmin : Boolean = false)
data class RequestData(val time: Timestamp)
//just wrapper for context objects
data class Context(val userData: UserData, val requestData : RequestData)
val contextDemoSchema = KGraphQL.schema<Context> {
query("me"){
_resolver { ctx: Context -> ctx.userData.name }
}
query("time"){
_resolver{ ctx : Context -> ctx.requestData.timestamp }
}
}
fun main(args : Array<String>) {
val context = Context(UserData("Jan Kowalski"), RequestData(System.currentTimeMillis()))
//fun execute(request: String, context: Context) where Context is type paramter of contextDemoSchema
val meName = contextDemoSchema.execute("{me}", context)
println(meName) // prints '{"data":{"me":"Jan Kowalski"}}'
}
from kgraphql.
I like it. Clean and easy to read/understand
from kgraphql.
0.2.4
has been released with support for custom context objects. Example snippet:
data class UserData(val name : String, val isAdmin : Boolean = false)
data class RequestData(val time: Timestamp)
//just wrapper for context objects
data class Context(val userData: UserData, val requestData : RequestData)
val contextDemoSchema = KGraphQL.schema(Context::class) {
query("me"){
resolver { ctx: Context -> ctx.userData.name }
}
query("time"){
resolver{ now : Boolean, ctx : Context -> if(now) ctx.requestData.timestamp else 0 }
}
}
fun main(args : Array<String>) {
val context = Context(UserData("Jan Kowalski"), RequestData(System.currentTimeMillis()))
//fun execute(request: String, context: Context) where Context is type parameter of contextDemoSchema
val meName = contextDemoSchema.execute("{me}", context)
println(meName) // prints '{"data":{"me":"Jan Kowalski"}}'
}
As you can see, schema creation invocations is KGraphQL.schema(Context::class){}
, not KGraphQL.schema<Context>{}
. Reasoning behind this is that I wanted to KGraphQL.schema {}
to be still valid, and second variant would lead to function signature clash. Besides, context argument can be declared in any position.
from kgraphql.
Nice!! Will try this a.s.p.
from kgraphql.
Hey @Paradoxia did you try it? If so, please let me know if it works as you expected.
from kgraphql.
Sorry for the delayed answer. I've been stuck in another project.
I've been trying to migrate to 0.2.4 but the compiler give me tons of errors and intellisense doesn't want to help me out.
interface SchemaService {
fun schema(): Schema
fun docs(): String
}
What should I add to : Schema
to avoid the One type argument expected for interface Schema<Context> : __Schema defined in com.github.pgutkowski.kgraphql.schema
error message.
I've created my own Context class (i call it SchemaContext).
from kgraphql.
No problem, thank you for quick response!
Handling parameterized context object forced us to add generic parameter to Schema
, so please try changing Schema
to Schema<SchemaContext>
from kgraphql.
Related Issues (20)
- Extension property not working HOT 1
- Support for suspendable property resolvers HOT 2
- There is no instruction to help a new user to start the server and the client in this example. How can I run the server and start query? HOT 2
- LocalDate coercion issue HOT 2
- Support for suspendable schema execution HOT 1
- Property resolver with context HOT 8
- Scalar types within variables not working HOT 1
- How would I handle query/mutation authentication? HOT 4
- Print Schema? HOT 1
- Adding Context parameter to resolver causes errors in introspection HOT 3
- Fragments not resolving correctly on same data node
- Nested Fragments fail with property does not exist HOT 2
- LocalDate when passed as query variable HOT 1
- Leaking top level
- Is this the right way with using resolvers on a type? HOT 2
- Support for suspendable unionProperty resolvers
- Implement a DataLoaderDSL for batching
- Caused by: java.lang.NoClassDefFoundError: kotlinx/coroutines/experimental/CommonPool HOT 1
- When overwriting a property, the GraphQL repeats the original property unless ignored
- release 0.3.1 build? HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from kgraphql.