2

我有一个应用程序在后端使用 Laravel 和 Lighthouse,在前端使用 Nuxt 和 Vuex-ORM/graphql-plugin。我在比较时遇到了困难,因为无论出于何种原因,有时数据会被查询或变异,而 ID 似乎是整数或字符串的混合体。

我正在努力确保每个 ID 实际上都是一个整数。每当我在前端 console.log 一个 Trip 时,那个 Trip 的 ID 仍然是一个字符串。当我在 graphql-playground 中运行查询时,它以字符串形式返回,但我认为这更多是因为它是一个“ID”标量类型,可以是 int 或字符串。或者其他的东西。我不知道,我还是很喜欢这个。

Trip.php:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class Trip extends Model
{
    protected $fillable = [
        'name', 'description', 'user_id'
    ];

    // automatically eager load todos and shopping_list_items
    protected $with = [
        'items', 'users'
    ];

    // define relationships
    public function users(): BelongsToMany
    {
        return $this->belongsToMany(User::class);
    }
}

trip.graphql:

extend type Query @guard(with: ["api"]) {
    trip(id: ID! @eq): Trip! @find
    trips: [Trip]! @field(resolver: "TripsQuery@find_by_user")
}

extend type Mutation @guard(with: ["api"]) {
    updateTrip(id: ID! trip: TripInput! @spread): Trip @update
}

type Trip {
    id: ID!
    name: String
    description: String
    created_at: DateTime!
    updated_at: DateTime!
    user_id: ID

    items: [Item]! @hasMany
    users: [User]! @hasMany
}

input TripInput {
    name: String
    description: String
    user_id: ID
}

行程.js:

import { Model } from '@vuex-orm/core';
import Item from './item';
import TripUser from './tripUser';
import User from './user';

export default class Trip extends Model {
  static entity = 'trips';
  static eagerLoad = ['items', 'users'];

  static fields () {
    return {
      id: this.number(0),
      name: this.string(''),
      description: this.string(''),
      user_id: this.number(0),

      // relationships
      items: this.hasMany(Item, 'trip_id'),
      users: this.belongsToMany(User, TripUser, 'trip_id', 'user_id')
    };
  }
};

规划.vue:

<script>
  import currentUser from '~/mixins/currentUser';
  import Trip from '~/data/models/trip';
  import tripsQuery from '~/apollo/queries/content/trips.gql';

  export default {
    name: 'Planning',

    middleware: 'authenticated',

    mixins: [currentUser],

    data: () => ({
      loading: 1,
    }),

    computed: {
      trips () {
        return Trip.query().where('owner_id', this.currentUser.id).all();
      }
    },

    async mounted () {
      const { trips } = await this.$store.dispatch('entities/simpleQuery', {
        query: tripsQuery,
        variables: {},
        bypassCache: false
      });
      console.log(typeof trips[0].id); // <--- returns 'string';
      Trip.insert({ data: [...trips] });
      this.selectedTrip = trips.length ? trips[0] : null;
      this.loading = 0;
    },

    head () {
      return {
        title: 'Planning'
      };
    }
  };
</script>

您可以在mountedVue 文件中函数的 console.log 中看到,id 仍然以字符串而不是整数形式返回。我如何确保它始终是整数?

更新:我认为我已经使用我正在使用的@vuex-orm/plugin-graphql 库将其缩小到一个更大的问题。我试图恢复一点,以便所有内容都使用字符串 id,但是我发现当我调度突变时,由于某种原因,有代码将 id 转换为整数。我将使用该库提交错误报告,然后关闭此问题。

4

1 回答 1

4

我想在这里插话并指出 ID 被设计为字符串,而不是错误。您在这个 SO 答案中看到了更多关于它的信息:https ://stackoverflow.com/a/47888604/11678503

简而言之,ID 是GraphQL 规范(2018 年 6 月工作规范)中定义的标量类型:

ID 标量类型表示唯一标识符,通常用于重新获取对象或作为缓存的键。ID类型的序列化方式与String相同;但是,它并不适合人类阅读。虽然它通常是数字,但它应该始终序列化为字符串。

虽然数据库中的 ID 通常是自动递增的数字键,但这绝不是标准。许多 API 使用哈希和 UUID,因为它取决于用例。因此,ID 始终可以是字符串,但不能始终是数字——因此为什么转换为字符串是更安全的选择。

所以我希望能弄清楚为什么 Lighthouse 以及graphql-php 库将 ID 转换为字符串。他们符合规范。

希望这有助于澄清事情!

于 2020-12-09T01:39:23.257 回答