Skip to content
This repository has been archived by the owner on May 16, 2019. It is now read-only.

Property resolver with context #42

Open
StefanLiebig opened this issue Dec 17, 2018 · 8 comments
Open

Property resolver with context #42

StefanLiebig opened this issue Dec 17, 2018 · 8 comments

Comments

@StefanLiebig
Copy link

While it is possible to pass an optional context object to the "execute" function of the Schema which than will be propagated to the "suspendResolver"/"resolver" functions of the "query" block, I have not found a way how this context object gets passed to the property resolvers.

(using version 0.3.0)

@shamresh
Copy link

Can you give a use case of where this would be used? (I am new to GraphQL and Kotlin :))

@StefanLiebig
Copy link
Author

The context could hold a security context which could be used to check permissions, e.g. restrict visibility of data.

@AlphonseSantoro
Copy link

You can access the context by using

type<Post>{
    property(Post::id){
        accessRule { post, ctx ->
            if(post.id == ctx.get<String>()) null else IllegalAccessException()
        }
    }
}

and

query("black_mamba") {
    resolver { -> Player("KOBE") }
    accessRule { ctx -> if (ctx.get<String>().equals("LAKERS")) null else IllegalAccessException() }
}

What I'm missing is that you can access the properties and context in the query itself.
e.g. I want a user to be able to read all posts but i dont want the user to edit posts of other users

@StefanLiebig
Copy link
Author

Ah, ok - Thanks!

.. but i dont want the user to edit posts of other users

Is this about mutations?

@AlphonseSantoro
Copy link

Is this about mutations?

Both, it's about accessing properties in each query/mutation.
When using the first example I gave, the access rule applies to all queries/mutations to that type. As of now i can't see there is any property access on query/mutation level.

@StefanLiebig
Copy link
Author

StefanLiebig commented Dec 20, 2018

Ok, I got your point! I have not yet used mutations, so I did not stumble upon this problem.

This 'accessRule' looks nice, but it prevents my use case. I do not want to do the permission checking in the graphql layer but a little bit deeper in the 'data' layer because a parallel REST-API also uses this 'data' layer.

So I would like to have the possibility to pass the context (more precise: just the authorization part of it) to the 'data' layer. The suspendResolver/resolver function inside a query accepts a context object as parameter so that I can forward it:

    query("timeEntries") {
        suspendResolver { ctx: Context, year: Int?, month: Int?, userId: UserId?, topicFK: Int?, timeEntryTypeFK: Int? ->
            // forward "ctx" to the "data" layer.
        }
    }

Unfortunatlly, this is not possible with the property resolver.

@pgutkowski
Copy link
Owner

Hi @StefanHUB and @AlphonseSantoro

You can use Context in resolvers of queries, extension properties and transformations (I have to update the documentation), see:

fun `client code can use context class in property resolver`(){

But if I understand correctly, you would like to declare "resolver" for Kotlin properties as well, with access to property and context?

DSL example (not implemented yet):

type<Actor> {
                property(Actor::name) {
                    resolver { actor : Actor, ctx: Context ->
                        if(ctx.get<UserData>()?.canAccessActorName){
                            actor.name
                        } else {
                            throw UnauthorizedAccessException()
                        }
                    }
                }
}

Would this solve your use case?

@NataliiaVallander
Copy link

NataliiaVallander commented Jan 11, 2019

UPDATE: Working from locally built version. Probably last release is too old
@pgutkowski This works, but still there is a problem -- schema became invalid. I am getting this in qraphiql:
Error: Invalid or incomplete schema, unknown type: null. Ensure that a full introspection query is used in order to build a client schema.
As I understand this is because Context become input type which is not defined.
If I am trying to define it as Input Type am getting an error that generic classes are not supported from handleInputValues method.
Do you have any suggestions how to fix this?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants