作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
克里斯托弗·摩尔的头像

克里斯托弗•摩尔

克里斯托弗•摩尔是一个拥有超过7年经验的全栈PHP开发人员. 他专门从事Laravel和Ember的开发.

工作经验

14

Share

如果你还不熟悉的话, GraphQL是一种用于与API交互的查询语言 提供了一些好处 与REST等可选架构相比. GraphQL在用作移动和单页面应用程序的端点时非常方便. GraphQL允许您相对轻松地查询请求中的嵌套和相关数据, 允许开发人员在与服务器的一次往返中获得所需的确切数据.

Laravel 是一个流行的,固执己见的PHP web框架. 它提供了许多内置工具来快速启动和运行应用程序, 但它也允许开发人员在需要时将自己的实现替换为Laravel的内置接口.

尽管GraphQL和Laravel的社区都在开源后迅速发展, 解释如何结合使用这两种技术的文档仍然很少.

因此,在本教程中,我将向您展示如何使用Laravel创建自己的GraphQL服务器.

Project Overview

图ql服务器概览图

在开始之前,我们需要熟悉我们正在尝试构建的项目. To do that, 我们将定义资源并创建GraphQL模式, 我们稍后将使用它来服务我们的API.

项目资源

我们的应用程序将包含两个资源: Articles and Users. 这些资源将被定义为GraphQL模式中的对象类型:

type User {
  id: ID!
  name: String!
  email: String!
  文章(文章:!]!
}

type Article {
  id: ID!
  title: String!
  content: String!
  author: User!
}

查看模式,我们可以看到两个对象之间存在一对多关系. 用户可以写很多篇文章,每篇文章都有一个指定的作者(用户).

现在我们已经定义了对象类型, 我们需要一种方法来创建和查询我们的数据, 那么让我们定义查询和变异对象:

type Query {
user(id: ID!): User
  users: [User!]!

  article(id: ID!): Article
  文章(文章:!]!
}

type Mutation {
  createUser(名称:字符串!, email: String!,密码:字符串!): User
  createArticle(标题:字符串!,内容:字符串!): Article
}

设置Laravel项目

现在我们已经定义了GraphQL模式,让我们启动并运行Laravel项目. 让我们先通过Composer项目创建一个新的Laravel:

/ / / / / / / / / / / /

只是为了确保一切正常, 让我们启动服务器,确保我们看到Laravel的默认页面:

$ CD larvel -graphql
$ PHP工匠服务
Laravel development server started: 

数据库模型和迁移

出于本文的目的,我们将使用SQLite. 因此,让我们对默认值进行以下更改 .env file:

DB_CONNECTION = sqlite
# DB_HOST=
# DB_PORT=
# DB_DATABASE =数据库.sqlite
# DB_USERNAME=
# DB_PASSWORD=

接下来,让我们创建数据库文件:

$ touch ./数据库/数据库.sqlite

Laravel附带了一个用户模型和一些基本的迁移文件. 让我们快速加一个 api_token 列到我们的在我们的 CreateUsersTable Laravel提供给我们的迁移文件:

/ /数据库迁移/ XXXX_XX_XX_000000_create_users_table.php
使用说明\迁移\ \数据库迁移;
数据库使用说明\ \模式\蓝图;
使用说明\ \外墙\模式的支持;

类CreateUsersTable扩展Migration
{
    /**
     *运行迁移.
     */
    公共功能up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->string('api_token', 80)->unique()->nullable()->default(null);
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     *反向迁移.
     */
    公共函数down()
    {
        模式:dropIfExists(“用户”);
    }
}

在本文后面讨论授权时,我们将回到这个附加专栏. 现在让我们继续创建文章模型和一个迁移文件来创建相关的表:

$ php工匠制作:模型文章-m

Note: m选项为我们新创建的文章模型创建一个迁移文件.

让我们对生成的迁移文件做一些调整:

使用说明\ \外墙\模式的支持;
数据库使用说明\ \模式\蓝图;
使用说明\迁移\ \数据库迁移;

类CreateArticlesTable扩展迁移
{
    /**
     *运行迁移.
     *
     * @return void
     */
    公共功能up()
    {
        Schema::create('articles', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->unsignedBigInteger('user_id');
            $table->string('title');
            $table->text('content');
            $table->timestamps();

            $table->foreign('user_id')->references('id')->on('users');
        });
    }

    /**
     *反向迁移.
     *
     * @return void
     */
    公共函数down()
    {
        模式:dropIfExists(“文章”);
    }
}

我们添加了一个外键指向 id on our users 表以及 title and content 我们在GraphQL模式中定义的列.

现在我们已经定义了迁移文件,让我们继续在数据库中运行它们:

$ PHP工匠迁移

接下来,让我们通过定义必要的关系来更新模型:

app/User.php
namespace App;

使用说明\ \须申报的通知;
使用Illuminate\Foundation\Auth\User作为Authenticatable;

类User扩展Authenticatable
{
    use Notifiable;

    /**
     *可大规模分配的属性.
     *
     * @var array
     */
    Protected $fillable = [
        'name', 'email', 'password',
    ];

    // ...

    /**
     * @return \照亮\ \雄辩的\ \ HasMany关系数据库
     */
    公共职能文章()
    {
        return $this->hasMany(Article::class);
    }
}
app/Article.php
namespace App;

使用说明\雄辩的\ \数据库模型;

类Article扩展Model
{
    /**
     *可大规模分配的属性.
     *
     * @var array
     */
    Protected $fillable = [
        “标题”、“内容”,
    ];

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    公共函数user()
    {
        return $this->belongsTo(User::class);
    }
}

Database Seeding

现在我们已经建立了模型和迁移,让我们建立数据库. 我们将从创建一些种子类开始 articles and users tables:

# # # # # # # # # # # 
$ php工匠制作:种子ArticlesTableSeeder

接下来,让我们设置它们来插入一些虚拟数据到我们的SQLite数据库中:

数据库/ / UsersTableSeeder种子.php
use App\User;
数据库使用说明\ \播种机;

类UsersTableSeeder扩展了Seeder
{
    /**
     *运行数据库种子.
     */
    公共函数run()
    {
        \ App \用户:截断();

        $faker = \ faker \Factory::create();
        $password = bcrypt('secret');

        \ App \用户::创建([
            'name'     => $faker->name,
            'email'    => 'graphql@test.com',
            'password' => $password,
        ]);

        for ($i = 0; $i < 10; ++$i) {
            \ App \用户::创建([
                'name'     => $faker->name,
                'email'    => $faker->email,
                'password' => $password,
            ]);
        }
    }
}
数据库/ / ArticlesTableSeeder种子.php
使用App \文章;
数据库使用说明\ \播种机;

类ArticlesTableSeeder扩展了Seeder
{
    /**
     *运行数据库种子.
     */
    公共函数run()
    {
        \ App \文章:截断();
        \ App \文章:使无防备();

        $faker = \ faker \Factory::create();

        \App\User::all()->each(function ($user) use ($faker) {
            Foreach (range(1, 5) as $i) {
                \ App \文章::创建([
                    'user_id' => $user->id,
                    'title'   => $faker->sentence,
                    'content' => $faker->paragraphs(3, true),
                ]);
            }
        });
    }
}
/数据库/ / DatabaseSeeder种子.php
数据库使用说明\ \播种机;

类databaseseder扩展了seder
{
    /**
     *播种应用程序的数据库.
     *
     * @return void
     */
    公共函数run()
    {
        $this->call(UsersTableSeeder::class);
        $this->call(ArticlesTableSeeder::class);
    }
}

最后,让我们继续运行数据库种子器,将一些数据放入数据库:

$ PHP工匠db:种子

Laravel灯塔和GraphQL服务器

现在我们已经设置好了数据库和模型,是时候开始构建GraphQL服务器了. Currently, Laravel有几个可用的解决方案, 但是对于这篇文章, 我们要用 Lighthouse.

Lighthouse是我几年前创建的一个包,最近它得到了越来越多的社区的支持. 它允许开发人员使用Laravel快速设置GraphQL服务器,并且只需要很少的样板,同时也足够灵活,允许开发人员定制它以适应几乎任何项目的需求.

Laravel灯塔和GraphQL服务器插图

让我们从将包拉入我们的项目开始:

$ composer require nuwave/lighthouse:.1.*"

接下来,让我们发布Lighthouse的配置文件:

$ php artisan vendor:publish——provider="Nuwave\Lighthouse\LighthouseServiceProvider"——tag=config

Note: 您还可以选择发布Lighthouse的默认模式文件,只需删除 --tag=config option. 但出于本文的目的,我们将从头创建模式文件.

如果我们看一下 配置/灯塔.php 你会注意到一个用于向Lighthouse注册模式文件的设置:

'schema' => [
    'register' => base_path('graphql/schema.graphql'),
],

所以让我们继续创建schema文件,设置用户对象类型和查询:

$ mkdir graphql
$ touch ./graphql/schema.graphql

/graphql/schema.graphql
type User {
  id: ID!
  name: String!
  email: String!
}

type Query {
  user(id: ID! @eq):用户@find
  users: [User!]! @all
}

您会注意到,我们的模式看起来与前面定义的模式类似,只是我们添加了一些标识符 模式指令.

让我们花点时间来分解我们定义的模式. 第一个定义是an object type called User 哪个和我们有关系 App\User eloquent model. We defined the id, name and email 作为可以从我们的 User models. 或者,这意味着 password, created_at and updated_at 列是无法从API查询的字段.

Next we have our Query 类型,它是进入API的入口点,可用于查询数据. 我们的第一个字段是 users 的数组 User object types. The @all 指令告诉Lighthouse运行一个Eloquent查询,使用 User 建模并得到所有结果. 这将与运行以下命令相同:

$users = \App\User::all();

Note: 灯塔知道在 \App\User 命名空间,因为 namespaces 选项在其配置文件中定义.

查询类型上定义的第二个字段是call user, which takes an id 作为参数,并返回一个 User object type. 我们还添加了两个指令来帮助Lighthouse自动为我们构建查询并返回单个查询 User model. The @eq 指令告诉Lighthouse在我们的 id column, and the @find 指令指示Lighthouse返回单个结果. 要使用Laravel的查询生成器编写这个查询,它看起来像这样:

$user = \App\User::where('id', $args['id'])->first();

查询GraphQL API

现在我们对Lighthouse如何使用我们的模式来创建查询有了一些了解, 让我们运行服务器并开始查询数据. 我们将从运行服务器开始:

$ PHP工匠服务
Laravel development server started: 

查询GraphQL端点, 您可以在终端或标准客户端(如Postman)中运行cURL命令. However, 以获得GraphQL的全部好处(例如自动完成), 错误高亮显示, documentation, etc., we’ll use GraphQL操场 (版本下载 here).

启动Playground时,点击“URL Endpoint”选项卡,然后输入 http://localhost:8000/graphql 将GraphQL操场指向我们的服务器. 在编辑器的左边, 我们可以查询我们的数据, 那么让我们从查询我们在数据库中播种的所有用户开始:

{
  users {
    id
    email
    name
  }
}

当您点击IDE中间的播放按钮(或单击 Ctrl+Enter),你会在右侧看到我们服务器的JSON输出,它看起来像这样:

{
  "data": {
    "users": [
      {
        "id": "1",
        “电子邮件”:“graphql@test.com",
        "姓名":"卡罗琳·鲍洛夫斯基"
      },
      {
        "id": "2",
        “电子邮件”:“kheaney@yahoo.com",
        "姓名":"露易丝·雷诺"
      },
      {
        "id": "3",
        “电子邮件”:“奥兰多.sipes@yahoo.com",
        "name": "Mrs. Dejah Wiza"
      },
      ...
    ]
  }
}

Note: 因为我们用Faker来建立数据库,数据库里的数据 email and name 字段会有所不同.

现在让我们尝试查询单个用户:

{
  user(id: 1) {
    email
    name
  }
}

对于单个用户,我们将得到以下输出:

{
  "data": {
    "user": {
      “电子邮件”:“graphql@test.com",
      "姓名":"卡罗琳·鲍洛夫斯基"
    }
  }
}

像这样查询数据是很好的开始, 但是,在一个项目中,您不太可能想要查询 all 因此,让我们尝试添加一些分页. 当你穿过灯塔的广阔视野 内置的指令, we have a @paginate 指令对我们来说是可用的,所以让我们像这样更新schema的查询对象:

type Query {
  user(id: ID! @eq):用户@find
  users: [User!]! @paginate
}

如果我们重载GraphQL操场 (Ctrl/Cmd + R) and try our users 再次查询,您将注意到我们得到一条错误消息,说明 无法在UserPaginator类型上查询字段id那么发生了什么呢?? 幕后故事, Lighthouse操作我们的模式,让我们获得一组经过分页的结果,并通过更改类的返回类型来实现 users field.

让我们通过在GraphQL操场的“文档”选项卡中检查我们的模式来仔细看看. 如果你看一下 users 字段,它返回a UserPaginator 它返回一个用户数组和一个定义的Lighthouse PaginatorInfo type:

类型UserPaginator {
  paginatorInfo: paginatorInfo!
  data: [User!]!
}

type PaginatorInfo {
  count: Int!
  currentPage: Int!
  firstItem: Int
  hasMorePages:布尔!
  lastItem: Int
  lastPage: Int!
  perPage: Int!
  total: Int!
}

如果您熟悉Laravel的内置分页,那么 PaginatorInfo 这种类型对你来说可能很熟悉. So, 查询两个用户, 获取系统中的用户总数, 检查一下我们有更多的页面可以循环浏览, 我们将发送以下查询:

{
  users(count:2) {
    paginatorInfo {
      total
      hasMorePages
    }
    data {
      id
      name
      email
    }
  }
}

这将为我们提供以下回复:

{
  "data": {
    "users": {
      " paginatorInfo ": {
        "total": 11,
        “hasMorePages”:真的
      },
      "data": [
        {
          "id": "1",
          "姓名":"卡罗琳·鲍洛夫斯基";
          “电子邮件”:“graphql@test.com"
        },
        {
          "id": "2",
          "姓名":"露易丝·雷诺";
          “电子邮件”:“kheaney@yahoo.com"
        },
      ]
    }
  }
}

Relationships

通常,在开发应用程序时,很多数据都是相关的. In our case, a User can write many Articles,让我们将那个关系添加到User类型并定义 Article type:

type User {
  id: ID!
  name: String!
  email: String!
  文章(文章:!]! @hasMany
}

type Article {
  id: ID!
  title: String!
  content: String!
}

这里,我们使用了另一个Lighthouse提供的模式指令 @hasMany,它告诉灯塔我们 User model has a \照亮\ \雄辩的\ \ HasMany关系数据库 与政府的关系 Article model.

现在让我们来查询新定义的关系:

{
  user(id:1) {
    articles {
      id
      title
    }
  }
}

这将为我们提供以下响应:

{
  "data": {
    "user": {
      "articles": [
        {
          "id": "1",
          "title": "Aut velit et temporibus但et tempora sint "."
        },
        {
          "id": "2",
          “title”:“Voluptatem是劳动,是voluptas。."
        },
        {
          "id": "3",
          "title": "Beatae sit et maximum consequence et natus toam "."
        },
        {
          "id": "4",
          "title": "Corrupti beatae cumque控告"."
        },
        {
          "id": "5",
          "title": "Aperiam quidem sit esse rem sed cupiditate "."
        }
      ]
    }
  }
}

最后,让我们把关系反过来,加上 author 与我们的关系 Article 对象类型使用Lighthouse的 @belongsTo Schema指令以及更新我们的 Query:

type Article {
  id: ID!
  title: String!
  content: String!
  author: User! @belongsTo(关系:“用户”)
}

type Query {
  user(id: ID! @eq):用户@find
  users: [User!]! @paginate
  article(id: ID! @eq):文章@find
  文章(文章:!]! @paginate
}

您将看到我们添加了一个可选的 relation argument to the @belongsTo directive. 这告诉灯塔使用 Articles model’s user 关系,并将其分配给 author field.

现在让我们查询文章列表并获取其关联作者:

{
  文章(数量:2){
    paginatorInfo {
      total
      hasMorePages
    }
    data {
      id
      title
      author {
        name
        email
      }
    }
  }
}

我们应该从服务器得到以下内容:

{
  "data": {
    "articles": {
      " paginatorInfo ": {
        "total": 55,
        “hasMorePages”:真的
      },
      "data": [
        {
          "id": "1",
          "title": "Aut velit et temporibus但et tempora sint ".",
          "author": {
            "姓名":"卡罗琳·鲍洛夫斯基";
            “电子邮件”:“graphql@test.com"
          }
        },
        {
          "id": "2",
          “title”:“Voluptatem是劳动,是voluptas。.",
          "author": {
            "姓名":"卡罗琳·鲍洛夫斯基";
            “电子邮件”:“graphql@test.com"
          }
        }
      ]
    }
  }
}

GraphQL Mutation

现在我们可以查询数据了,让我们创建一些突变来创建一些新的用户和文章. 我们将从我们的用户模型开始:

type Mutation {
  createUser(
    name: String!
    email: String! @rules(apply: ["email", "unique:users"])
    password: String! @bcrypt @rules(apply: ["min:6"])
  ): User @create
}

现在让我们分解这个模式定义. 我们创造了一个变种,叫做 createUser 它有三个参数(name, email, and password). 我们应用了 @rules 给我们双方的指示 email and password arguments. 这可能看起来有点熟悉,因为它类似于 validation logic Laravel提供了它的控制器.

接下来,我们把 @bcrypt directive to our password field. 这将在密码传递给新创建的模型之前对其进行加密.

最后,为了帮助我们创建新的模型,Lighthouse提供了一个 @create Schema指令,它将接受我们定义的参数并创建一个新模型. 在控制器中执行相同的逻辑如下所示:

名称空间的应用程序\ Http \控制器;

使用说明\ Http \请求;

类UserController扩展控制器
{
    /**
     *创建一个新用户.
     *
     * @param \Illuminate\Http\Request $ Request
     * @return \Illuminate\Http\Response
     */
    存储(请求)
    {
        $data = $this->validate($request, [
            'email' => ['email', 'unique:users'],
            'password' => ['min:6']
        ]);

        $user = \App\ user::create($data);

        return response()->json(['user' => $user]);
    }
}

现在我们已经设置了createUser突变字段, 让我们继续在GraphQL操场中运行它:

mutation {
  createUser(
    name:"John Doe"
    email:"john.doe@example.com"
    密码:“秘密”
  ) {
    id
    name
    email
  }
}

我们应该得到以下输出:

{
  "data": {
    "createUser": {
      "id": "12",
      "name": "John Doe",
      "email": "john.doe@example.com"
    }
  }
}

GraphQL身份验证和授权

因为我们需要加上a user_id to our Article 现在是学习GraphQL/Lighthouse中的身份验证和授权的好时机.

image alt text

要对用户进行身份验证,我们需要向他们提供一个 api_token,所以让我们创建一个突变来处理它,我们将添加 @field 指令,将Lighthouse指向一个将处理逻辑的自定义解析器. 我们将解析器设置为与 定义控制器 在Laravel中使用 resolver argument.

With the @field 指令定义时,我们会告诉灯塔 login 变异是运行时,使用的 createToken method on our App \ GraphQL \ \ AuthMutator突变 class:

type Mutation {
  # ...

  login(
    email: String! 
    password: String!
  ):字符串@field(解析器:"AuthMutator@resolve")
}

Note: 您不需要在这里包含整个名称空间. In the lighthouse.php 在配置文件中,您将看到我们为我们的突变设置了命名空间 应用\ \ GraphQL \ \突变 但是,如果愿意,您可以使用完整的名称空间.

让我们使用Lighthouse的生成器来创建新的mutator类:

$ php工匠灯塔:突变AuthMutator

接下来,让我们像这样更新解析器函数:

名称空间的应用程序\ GraphQL \突变;

使用说明\ \ Arr的支持;
使用说明\ \ Str的支持;
使用说明\ \外墙\身份验证的支持;
使用GraphQL \ \ \ ResolveInfo定义类型;
使用Nuwave \灯塔\ \ \ GraphQLContext合同的支持;

类AuthMutator
{
    /**
     *返回字段的值.
     *
     * @param null $rootValue通常包含从父字段返回的结果. 在这种情况下,它总是' null '.
     * @param mixed[] $args传入字段的参数.
     * @param \Nuwave\Lighthouse\Support\Contracts\GraphQLContext $context在单个查询的所有字段之间共享的任意数据.
     * @param \GraphQL\Type\Definition\ResolveInfo $ ResolveInfo查询本身的信息, 例如执行状态, the field name, 从根目录到字段的路径, and more.
     * @return mixed
     */
    公共函数解析($rootValue, array $args, GraphQLContext $context, ResolveInfo $ ResolveInfo)
    {
        $credentials = Arr::only($args, ['email', 'password']);

        if (Auth::once($credentials)) {
            $token = Str::random(60);

            $user = auth()->user();
            $user->api_token = $token;
            $user->save();

            return $token;
        }

        return null;
    }
}

现在我们已经设置好了解析器, 让我们测试一下,并尝试在GraphQL操场中使用以下突变来获得一个API令牌:

mutation {
  登录(电子邮件:“graphql@test.com”,密码:“秘密”)
}

我们应该得到这样一个令牌:

{
  "data": {
    “登录”:“VJCz1DCpmdvB9WatqvWbXBP2RN8geZQlrQatUnWIBJCdbAyTl3UsdOuio3VE”
  }
}

Note: 一定要复制从登录突变返回的令牌,以便稍后使用它.

接下来,让我们添加一个查询字段,它将返回经过身份验证的用户,以确保我们的逻辑正常工作. 我们将添加一个名为 me 使用灯塔的 @auth 指令返回当前已验证的用户. 我们还会设置 guard 参数等于 api 因为这就是我们验证用户的方式.

type Query {
  # ...
  我:用户@auth(守卫:“api”)
}

现在让我们运行查询. 在GraphQL操场中, 你可以通过双击底部的“Http headers”选项卡来设置你的请求头. 我们使用JSON对象添加标题, 因此,为每个请求添加一个承载令牌, 你可以补充以下内容:

{
  "授权":"Bearer VJCz1DCpmdvB9WatqvWbXBP2RN8geZQlrQatUnWIBJCdbAyTl3UsdOuio3VE"
}

Note: 将承载令牌替换为运行时收到的令牌 login query.

现在让我们运行 me query:

{
  me {
    email
    articles {
      id
      title
    }
  }
}

我们应该得到这样的输出:

{
  "data": {
    "me": {
      “电子邮件”:“graphql@test.com",
      "articles": [
        {
          "id": "1",
          “title”:“Rerum pecpecatis et quos ococatationem”."
        },
        {
          "id": "2",
          "title": " place quia cumque laudantim option voluptatem sed qui "."
        },
        {
          "id": "3",
          “title”:“option voluptatem et itaque sit animi”."
        },
        {
          "id": "4",
          "title": " except in and qui dolor and perspicitis adipisci "."
        },
        {
          "id": "5",
          "title": "Qui nemo blditiis sed fugit consequatur "."
        }
      ]
    }
  }
}

Middleware

现在我们知道我们的身份验证工作正常, 让我们创建最后一个突变,使用当前经过身份验证的用户创建一篇文章. We’ll use the @field 指令将Lighthouse指向我们的解析器,我们还将包含一个 @middleware 指令,以确保用户已登录.

type Mutation {
  # ...

  createArticle(标题:字符串!,内容:字符串!): Article 
    @field(解析器:“ArticleMutator@create”)
    @middleware(检查:["身份验证:api "])
}

首先,让我们生成一个突变类:

$ php工匠灯塔:突变ArticleMutator

接下来,让我们用以下逻辑更新这个mutator:

名称空间的应用程序\ GraphQL \突变;

使用Nuwave \灯塔\ \ \ GraphQLContext合同的支持;

类ArticleMutator
{
    /**
     *返回字段的值.
     *
     * @param null $rootValue
     * @param mixed[] $args
     * @param \Nuwave\Lighthouse\Support\Contracts\GraphQLContext $context 
     * @return mixed
     */
    public function create($rootValue, array $args, GraphQLContext $context)
    {
        $article = new \App\ article ($args);
        $context->user()->articles()->save($article);

        return $article;
    }
}

Note: 我们重命名了默认值 resolve function to create. 您不需要为每个解析器创建一个新类. 相反,如果更有意义的话,您可以将逻辑分组在一起.

最后,让我们运行新的突变并检查输出. 一定要保存好 Authorization 头从我们之前的查询“HTTP头”选项卡:

mutation {
  createArticle(
    题目:“用Laravel构建GraphQL服务器”
    内容:“以防你目前不熟悉它, GraphQL是一种用于与API交互的查询语言..."
  ) {
    id
    author {
      id
      email
    }
  }
}

我们应该得到以下输出:

{
  "data": {
    " createArticle ": {
      "id": "56",
      "author": {
        "id": "1",
        “电子邮件”:“graphql@test.com"
      }
    }
  }
}

Wrapping Up

回顾一下,我们已经利用Lighthouse为我们的Laravel项目创建了一个GraphQL服务器. 我们使用了一些内置的模式指令, 已创建的查询和变更, 负责授权和认证工作.

Lighthouse允许您做更多的事情(例如允许您创建自己的 自定义模式指令),但出于本文的目的,我们坚持基础知识,并且我们能够使用相当少的样板文件建立并运行GraphQL服务器.

下次您需要为移动或单页面应用程序设置API时,请务必考虑 GraphQL 作为查询数据的一种方式!

了解基本知识

  • 什么是GraphQL服务器?

    实现GraphQL规范并公开API端点供客户端查询的服务器.

  • GraphQL的好处是什么?

    GraphQL是强类型的, self-documenting, 并支持声明式数据获取, 它允许客户查询他们需要的确切数据,并使构建强大而深入的开发人员工具成为可能.

  • 为什么要使用GraphQL?

    GraphQL通常用于需要查询相关数据的场景,或者在多次往返服务器可能对客户体验产生负面影响的环境中使用.

  • 什么是Laravel ?为什么要使用它?

    Laravel是一个用PHP语言构建的web框架. 它的需求量很大,因为它能够通过为开发人员提供一个详尽的工具包来简化开发体验,以便快速使用和迭代.

  • Laravel的优势是什么?

    Laravel提供了许多开箱即用的必要工具来构建web应用程序. 它也是开源的, 这使得社区中的人能够为现代web开发中的许多常见边缘情况做出贡献.

  • Laravel是前端还是后端?

    Laravel通常被认为是一个后端web服务器. However, 它包括一个名为“Blade”的富有表现力的模板引擎,,这就简化了前端的开发.

  • Laravel受欢迎吗?

    Currently, Laravel是所有语言中最流行的web框架之一,它的社区正在继续快速增长.

就这一主题咨询作者或专家.
Schedule a call
克里斯托弗·摩尔的头像
克里斯托弗•摩尔

Located in 吉尔伯特,亚利桑那州,美国

Member since August 3, 2015

About the author

克里斯托弗•摩尔是一个拥有超过7年经验的全栈PHP开发人员. 他专门从事Laravel和Ember的开发.

Toptal作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

工作经验

14

世界级的文章,每周发一次.

订阅意味着同意我们的 privacy policy

世界级的文章,每周发一次.

订阅意味着同意我们的 privacy policy

Toptal开发者

Join the Toptal® community.