在 Laravel/Lighthouse GraphQL API 中实现搜索功能

Posted

技术标签:

【中文标题】在 Laravel/Lighthouse GraphQL API 中实现搜索功能【英文标题】:Implementing Search funtionality in Laravel/Lighthouse GraphQL API 【发布时间】:2019-11-04 21:18:14 【问题描述】:

我正在创建现有 API 的 GraphQL 实现。我正在使用 Laravel 5.8 和 Lighthouse 3.7。

我想知道如何使用它来实现搜索功能 - 类似于...

scheme.graphql

type Query 
    userSearch(name: String, email: String, phone: String, city_id: Int): [User] #Custom Resolver - app/GraphQL/Queries/UserSearch.php

type User 
    id: ID!
    name: String!
    email: String
    phone: String
    credit: Int
    city_id: Int
    city: City @belongsTo

用户搜索.php

public function resolve($rootValue, array $args, GraphQLContext $context, ResolveInfo $resolveInfo)

    $q = app('db')->table('users');
    foreach($args as $key => $value) 
        $q->where($key, $value);
    
    $users = $q->get();

    return $users;

这可行 - 但仅适用于查询返回的字段。


    userSearch(name:"Picard") 
        id          # This will work
        name        # This will work
        city       # These wont.
            id      # These won't work
            name    # These won't work
        
    

我尝试时会收到此错误...

"debugMessage": "Argument 1 passed to Nuwave\\Lighthouse\\Schema\\Directives\\RelationDirective::Nuwave\\Lighthouse\\Schema\\Directives\\closure() must be an instance of Illuminate\\Database\\Eloquent\\Model, instance of stdClass given, called in /mnt/x/Data/www/Projects/Phoenix/vendor/nuwave/lighthouse/src/Schema/Factories/FieldFactory.php on line 221"

我知道出了什么问题 - resolve 函数中的 $users 返回一个可交互的对象 - 而不是一个模型 - 如 hasManybelongsTo 返回。我想知道这样做的正确方法是什么。

【问题讨论】:

你可能需要一些->join('cities')(左?)在解析器中 您尝试做的事情应该可以在不使用自定义解析器的情况下完成。只需在您的参数上使用eq 指令而不是lighthouse-php.com/3.7/api-reference/directives.html#eq 【参考方案1】:

您尝试做的事情应该可以在不使用自定义解析器的情况下进行。

您应该能够使用以下类似的东西来做到这一点

type Query 
    userSearch(name: String @eq, email: String @eq, phone: String @eq, city_id: Int @eq): [User] @paginate

type User 
    id: ID!
    name: String!
    email: String
    phone: String
    credit: Int
    city_id: Int
    city: City @belongsTo

这里我们使用paginate method 并用一些constraints 扩展它。

【讨论】:

这很有帮助——但不是我想要的。我想在返回数据之前在解析器中添加一些过滤器(比如 status = 1 和其他一些)。 您可以通过使用范围指令来做到这一点,然后将范围添加到您的用户模型中。否则,如果您可以展示您真正想要的完整示例,那么我会尽力提供帮助。【参考方案2】:

我在整个项目中尝试过的最佳方法是在 User 模型中添加一个公共静态 scopeSearch 函数并在那里执行搜索,然后轻松使用下面的代码进行搜索:

users(q: String @search): [User]
@paginate(model: "App\\Models\\User")

@search 将触发模型中的搜索功能。

【讨论】:

以上是关于在 Laravel/Lighthouse GraphQL API 中实现搜索功能的主要内容,如果未能解决你的问题,请参考以下文章

在 Laravel Lighthouse 中添加自定义类型和解析器

Laravel Lighthouse 配置 - 无法找到可发布的资源

变异中的 Laravel LightHouse GraphQL DateTime 输入始终为空

Laravel Lighthouse GraphQL - 在服务器端排序

Laravel Lighthouse 限制突变场

Laravel Lighthouse 中的授权