Giter VIP home page Giter VIP logo

Comments (26)

chrissm79 avatar chrissm79 commented on July 19, 2024 5

Hey @olivernybroe,

If you trying to filter something that is using the @belongsTo, @hasMany or @paginate directives you could just use the scopes argument like so and it will pass the field's arguments to your scope.

type User {
  posts(active: Boolean): [Post!]! @hasMany(scopes: ["active"])
}
class Post extends Model
{
    public function scopeActive($query, array $args)
    {
        return $query->when(!empty($args['active']), function ($q) use ($active) {
            return $q->where('active', $args['active']);
        });
    }
}

Otherwise, you just create an argument on the field and use it in your resolver

type User {
  avatar(size: String!): String @field(resolver: "App\\Http\\GraphQL\\UserType@avatar")
}
class UserType
{
    public function avatar($root, array $args)
    {
        // Here the $root could be your User model (or whatever you assigned to the User type)
        return $root->avatar($args['size']);
    }
}

from lighthouse.

chrissm79 avatar chrissm79 commented on July 19, 2024 3

@olivernybroe, I'm probably going to have to pass some sort of parser instance (that you can grab the queryBuilder off of) through the $arg array. This way I can do things like between, or, and (which would require some sort of key). But if you're using these new filters on the @paginate, @belongsTo or @hasMany relationships then you don't even need to worry about the query builder as Lighthouse will handle that behind the scenes. So you could do something like:

type Query {
  posts(
    active: Boolean @eq
    authors: [Int] @in(key: "user_id")
    start: DateTime @between(key: "created_at")
    end: DateTime @between(key: "created_at")
  ): [Posts!]! @paginate(type: "paginator") # This could also be a `@hasMany` or `@belongsTo` on another type
}

And it would just work!

from lighthouse.

olivernybroe avatar olivernybroe commented on July 19, 2024

@chrissm79 Thanks for the feedback.
Hmm it's a little awkward having to add a scope for filtering by id. But I guess I can make a custom directive instead?

from lighthouse.

kikoseijo avatar kikoseijo commented on July 19, 2024

The @field(resolver: "App\\Http\\GraphQL\\UserType@avatar") can do the job also.

You just tell where to resolve and take the input from $this->args on resolve function.

Check examples here:
https://github.com/nuwave

from lighthouse.

olivernybroe avatar olivernybroe commented on July 19, 2024

Right now my query looks like this

agreements(id: ID): [Agreement!]! @paginate(model: "Agreement", type: "connection", scopes: ["byAuth"])

With the @field I have to do a lot of the work manually, so was thinking about adding a ArgDirective like this

agreements(id: ID @filterBy(field: "id")): [Agreement!]! @paginate(model: "Agreement", type: "connection", scopes: ["byAuth"])

Just trying to find out how to access the query from a ArgMiddleware.
As I kinda like the syntax I made, as it doesn't bloat my scopes when just filtering by id.

from lighthouse.

kikoseijo avatar kikoseijo commented on July 19, 2024

What client you using?

I guess the magic its a bit limited, you trying to have all done from the schema,
Question for client its to know how should you response be made.,

here its a pagination example on root fields. #70
If you dont need pagination just build your own query resolve function, you can even use a repository function,

from lighthouse.

olivernybroe avatar olivernybroe commented on July 19, 2024

Setting it up with relay pagination.

Yes I am trying to do as much from schema as possible, just trying to figure out how to do it the best possible way with lighthouse.

from lighthouse.

olivernybroe avatar olivernybroe commented on July 19, 2024

But I guess the most clean way is to do it with scopes then, thanks!

from lighthouse.

chrissm79 avatar chrissm79 commented on July 19, 2024

@olivernybroe I LOVE the idea of argument filters! I have to figure out how to get it to work with @paginate, @belongsTo and @hasMany (maybe passing them through the $args variable), but I could see all kinds of possibilities. I'll re-open and label this as v2.x

from lighthouse.

olivernybroe avatar olivernybroe commented on July 19, 2024

@chrissm79 oh nice!

I don't know much about the internal system, but would it be possible to just pass the querybuilder? If we have access to the query we can pretty much do everything and then we would be able to make the argument filter directive relatively easy.

from lighthouse.

olivernybroe avatar olivernybroe commented on July 19, 2024

Also if we need some kind of way to specify filtering type eg. LIKE, EQ, NEQ and so on.

from lighthouse.

kikoseijo avatar kikoseijo commented on July 19, 2024

Wow, +1

from lighthouse.

olivernybroe avatar olivernybroe commented on July 19, 2024

Well done!
Smart solution with making a directive for each type, also solves the issue for coming with a good name.

Could we do so @in can be used with global ID?

Posts(author: [ID] @in(type: "User", key: "id") 

And then we can automatically lookup the user type id field and check if it has @globalid on it and then decide it.

from lighthouse.

chrissm79 avatar chrissm79 commented on July 19, 2024

@olivernybroe The last beta release has some argument filters to use!! The best way to see the possibilities (currently) is to check out the tests.

I just noticed your question about globalId fields. I think I can allow the @globalId directive to be added to an argument which will decode it before the query runs and would look like this:

type Query {
  # filter users with an `id` in the provided array and 
  # decodes the global id(s)
  users(include: [ID] @globalId @in(key: "id")): [User!]!
    @paginate(model: "App\\\Models\\\User")
}

and you'd query it like so:

{
  users(include: ["global-id-1", "global-id-2"] count: 15) {
    # only returns users with the ids provided (which will be decoded)
    name
    email
  }
}

I'll follow up if I get global id's to work this way.

from lighthouse.

kikoseijo avatar kikoseijo commented on July 19, 2024

@chrissm79 you awesome,
but, maybe, last commit can have an error? when you try to list routes.

Schema must contain unique named types but contains multiple types named Node
(see http://webonyx.github.io/graphql-php/type-system/#type-registry)

UPDATE:
having a second router caused this error, having middleware no need to have multiple endpoints, but,,,

from lighthouse.

hailwood avatar hailwood commented on July 19, 2024

Hey @chrissm79

The filters look great (I've only read through the tests)!

I see we could do @where(operator: "like") if we want a where like, but I feel that would be a common enough request that we should just add a @whereLike or simply @contains directive also and make it smart enough to check if the input value has any %, if it doesn't then wrap the entire thing in %'s?

from lighthouse.

chrissm79 avatar chrissm79 commented on July 19, 2024

@kikoseijo I'll check that out. The tests passed but I haven't pulled it into my project yet. However, it sounds like there is a type in the schema that's been declared twice (that or for some reason the scheme file is being generated more than once). I'll report back if I see something on my end when I update my dependencies to use the new beta.

@hailwood I get the point with the @whereLike. Maybe I could add an enum that could be WILDCARD, START or END to take care of the % placement.

from lighthouse.

hailwood avatar hailwood commented on July 19, 2024

@chrissm79 so what would that look like?

from lighthouse.

chrissm79 avatar chrissm79 commented on July 19, 2024

@hailwood Actually, I might need to use strings vs an enum (I might get an error since the enum isn't included in the user's schema). But it would look like the following:

type User {
  name: String!
}

type Query {
  # SELECT * FROM `users` WHERE `name` LIKE "{$name}"
  users(name: String @whereLike): [User!]!

  # SELECT * FROM `users` WHERE `name` LIKE "%{$name}"
  users(name: String @whereLike(filter: "starts_with")): [User!]!

  # SELECT * FROM `users` WHERE `name` LIKE "{$name}%"
  users(name: String @whereLike(filter: "ends_with")): [User!]!
  
  # SELECT * FROM `users` WHERE `name` LIKE "%{$name}%"
  users(name: String @whereLike(filter: "wildcard")): [User!]!
}

from lighthouse.

kikoseijo avatar kikoseijo commented on July 19, 2024

@chrissm79 forget it, i had a second router defined, from when i was playing with auth.
All fine. thanks anyway,

from lighthouse.

hailwood avatar hailwood commented on July 19, 2024

@chrissm79 interesting, although by defining it like that we actually like control away from the client right? Like a client couldn't then on your third example say "actually, I want a starts_with fillter"?

from lighthouse.

olivernybroe avatar olivernybroe commented on July 19, 2024

@chrissm79 Makes sense to let us define a default like operator. However I think you should give us more control, so we eg. Can say whereLike(starts_with: "___" ends_with: "%") it gives more control and doesn't hide what's happening as much.

@hailwood client still has full control. His example just gives us an default Wildcard to set. You can for example make the starts_with filter to a Wildcard filter by writing my search text%.

from lighthouse.

hailwood avatar hailwood commented on July 19, 2024

@chrissm79 / @olivernybroe did we get anywhere with defining @globalId on a filter?
I can't seem to get this to work? (no errors, just not decoded)

from lighthouse.

olivernybroe avatar olivernybroe commented on July 19, 2024

@hailwood, I haven't tested it, but it might work if you add the @globalId directive before the filter directive.

from lighthouse.

hailwood avatar hailwood commented on July 19, 2024

@olivernybroe unfortunately that doesn't seem to work either, I tried it in both positions.

from lighthouse.

spawnia avatar spawnia commented on July 19, 2024

Argument filters are available as of v2.1, you can check the docs https://lighthouse-php.netlify.com/docs/directives-queries.html

from lighthouse.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.