如果你想在Laravel中使用GraphQL,Lighthouse是一个不错的选择

我们正在使用Laravel与GraphQL一起部署生产环境的服务器。通过使用Lighthouse库,我们能够轻松搭建它。以下是我们在搭建过程中积累的经验。

image.png

结论就是

    • Laravel + GraphQL は、 Laravel の柔軟性と GraphQL の堅牢性がいい感じにマッチしている

 

    • Laravel で GraphQL やるなら、 Lighthouse 良い

 

    Schema をダンプしてチームでシェアするといい感じになる

在现实世界中应用GraphQL

我认为使用GraphQL的动机有以下几点。

    • 型安全な Web API を作りたい

 

    • 入出力を明確にしたい

 

    フロントとサーバー間の仕様書を、動いているコードから明確に作りたい

然而,阻碍的是

    • 既存のサービスのロジックを使いまわしたい

 

    徐々に移行したい。三ヶ月かかります、みたいなのはきつい

我认为一种常见的情况是将GraphQL与现有的框架结合起来,并逐步引入它。例如,在新开发的API中选择GraphQL。

在这种情况下,由于开发资源受限,能够轻松地创建GraphQL服务器非常重要。使用像Laravel这样的LL系语言框架的原因之一可能是能够以低学习成本快速进行开发。从团队文化的角度来看,将功能迅速交付给用户可能比花时间准确地完成更为重要,即使有些bug也可以容忍。在这种情况下,如果编写大量GraphQL类型定义会增加工作负担,那么作为团队采用它可能会很困难。

Lighthouse可以在最小的努力下利用类型定义来构建GraphQL服务器。我们来与其他GraphQL库进行比较。

使用Laravel开发时的GraphQL选择

    • laravel-graphql

graphql-laravel

laravel-graphql から派生したので、使い勝手は大体同じ

Lighthouse

灯塔的特点

和他的两个库相比,它非常简洁,可以像GraphQL一样编写。类似于Node.js的Apollo-Server,很容易进行比较。

型定义很简单

Laravel-GraphQL 可以用以下一种方式进行原意的表达:
拉韦尔-GraphQL

class UserType extends GraphQLType
{
    protected $attributes = [
        'name' => 'User',
        'description' => 'A user'
    ];

    public function fields()
    {
        return [
            'id' => [
                'type' => Type::nonNull(Type::int()),
                'description' => 'The id of the user'
            ],
            'email' => [
                'type' => Type::string(),
                'description' => 'The email of user'
            ],
            'posts' => [
                'type' => Type::listOf(GraphQL::type('Post')),
                'description' => 'The posts of user'
            ]
        ];
    }

    protected function resolveEmailField($root, $args)
    {
        return strtolower($root->email);
    }
}

灯塔

type User {
  # The id of the user
  id: ID!

  # The email of user
  email: String

  # The posts of user
  posts: [Post!] @hasMany
}

你是否注意到了明显的简化?

设计的思路是这样的,即读取和使用GraphQL文件。

顺便提一下,没有针对特定属性(比如 resolveEmailField)的解析器,但似乎可以使用魔法方法来解决。在上面的例子中,可以使用 User#getEmailAttribute 这样的方法。

以下是对原文的中文本地化释义:

可以用GraphQL编写查询定义。

Laravel-GraphQL是一种Laravel框架的插件。

'schemas' => [
    'default' => [
        'query' => [
            'users' => 'App\GraphQL\Query\UsersQuery'
        ],
        'mutation' => [
            'updateUserEmail' => 'App\GraphQL\Query\UpdateUserEmailMutation'
        ]
    ],
],

灯塔

type Query {
  users: [User] @field(resolver: "App\\GraphQL\\User@resolve")
}
type Mutation {
  updateUserEmail(email: String): User @field(resolver: "App\\GraphQL\\Query\\UpdateUserEmailMutation")
}

在Laravel-GraphQL中,您有两个选项来配置或使用`GraphQL::addSchema(’users’,…)`门面。而在Lighthouse中,您需要在graphql文件中指定。

个人来说,我觉得配置文件和外观模式有点不同,如果可以的话,我更想用GraphQL来定义。

由于Lighthouse可以加载其他的graphql文件,因此分割变得简单,同时还可以一目了然地知道查询接受什么并返回什么。

在建立关系时,能够避免N+1问题。

GraphQL的关联是一个令人头痛的问题,通常需要解析查询并根据需要进行Eager Loading。我记得目前GraphQL-Rails也是这样,未来可能会进行改进。

在Laravel-GraphQL中也是一样的,这里的文档中提供了实际的代码示例。

$fields = $info->getFieldSelection($depth = 3);

$users = User::query();

foreach ($fields as $field => $keys) {
    if ($field === 'profile') {
        $users->with('profile');
    }

    if ($field === 'posts') {
        $users->with('posts');
    }
}

是的。每次创建查询都要这样做吗?使用GraphQL有什么意义…

灯塔会自动为我们处理这个。只需指定 @hasMany 指令,它会自动解决关系并返回解决了 N+1 问题的查询结果。真厉害。

追踪代码发现似乎使用了Union查询。事实上,我在SQL日志中也看到了同样的情况。

生成 schema.graphql 的动作

Lighthouse 提供了一个名为 php artisan lighthouse:print-schema 的命令,可以使用它输出模式。

使用GraphDoc等工具,将其输出为有活力的HTML文档是一个不错的选择。

    • https://github.com/2fd/graphdoc

https://2fd.github.io/graphdoc/pokemon/ (デモ)

另外,在 CI 中,通过生成这类文档,并将其存储为 S3 上的静态网站,再与前端工程师共享,你就能够建立起一个很棒的前端环境。

在当前版本的 Laravel-GraphQL 中似乎没有命令来转储 Schema。

开发非常活跃

在这个 laravel-graphql 的问题中,由于近三个月没有更新,大家都倾向于使用 Lighthouse。我也看了这个帖子后进行了迁移(因为项目已经进行到了后期,所以有点困难哈哈)。

到目前为止(2018/08/11),根据Lighthouse的提交时间是在一天前,而且对问题的回复也非常迅速,所以对于未来也可以期待。

例如,对我提交的问题,他们很负责地给予了回复,并表示希望将其采纳。这让我感动不已。

我暂时会保持这个问题的开放,以便讨论如何将政策应用到具体的模型实例上。很想得到更多的反馈/听到更多的应用案例。

由于目前明星数量不是很多,因此可能注目度较低。

【补充说明】

在写这篇文章的8个月后(2019/03/21),仍然很活跃,最近两天还提交了代码并进入了3版本的测试阶段。

经过调查,我发现负责制作的是一家名为Nuwave的美国公司,他们似乎是一家从事Laravel和GraphQL相关委托开发的公司。所以他们能提供高质量的代码、活跃的开发、易于阅读的文档和友善的社区,并不足为奇。

文件非常齐全

laravel-graphql的文档相对而言比较简洁。从文档的意义上来说,只有Readme.md和docs/advanced.md这两篇实质性的文档。

灯塔拥有专门的仓库,非常易读。

    • https://github.com/nuwave/lighthouse-docs

 

    https://lighthouse-php.netlify.com/

此外,还有一个名为“如何…”的问题由有志发起,这里汇集了如何应对这种情况的信息。这对我来说非常有帮助。

然而,似乎文件的导入有些滞后,虽然存在一些隐而未见的功能,但感觉并没有在文件中体现出来。

如果想要创建一个自己的 Directive,就需要阅读现有的源代码。不过别担心,因为它们都是写得很易读的,所以并不会太费劲。

总结

虽然一些人可能会感到不适应、抵触或者对这种严格执行的方式有所抵触,但这种方式与 Apollo 和 GraphQL-Ruby 相似,我并不担心。

如果你喜欢简洁的框架或者希望像 PHP 那样定义查询,也许你会更喜欢 laravel-graphql,但是,在使用 Laravel 的时候就会感觉有些束缚……这是有所顾虑的。毕竟它是开源软件。

虽然星级还不够多,但这是一个值得关注的库。

因为我个人非常喜欢Lighthouse,所以我狂赞了它,但如果更多的人能使用它就好了。

如果有需要的话,我会考虑制作一些教程之类的东西。

顺便

如果有人想要使用Laravel + GraphQL进行开发,我可以介绍那些在https://lighthouse-php.com/users/上列出的公司,请告诉我。

广告
将在 10 秒后关闭
bannerAds