我看了这个问题:How to use or resolve enum types with graphql-tools?
而且,此文档:https://www.apollographql.com/docs/graphql-tools/scalars/#internal-values
现在,我要自定义graphql enum
的值。
typeDefs.ts
:
import { gql } from 'apollo-server';
export const typeDefs = gql`
enum Device {
UNKNOWN
DESKTOP
HIGH_END_MOBILE
TABLET
CONNECTED_TV
}
type CampaignPerformanceReport {
campaignNme: String!
campaignId: ID!
device: Device
}
type Query {
campaignPerformanceReports: [CampaignPerformanceReport]!
}
`;
resolvers.ts
:
import { IResolvers } from 'graphql-tools';
import { IAppContext } from './appContext';
export const resolvers: IResolvers = {
Device: {
UNKNOWN: 'Other',
DESKTOP: 'Computers',
HIGH_END_MOBILE: 'Mobile devices with full browsers',
TABLET: 'Tablets with full browsers',
CONNECTED_TV: 'Devices streaming video content to TV screens',
},
Query: {
async campaignPerformanceReports(_, __, { db }: IAppContext) {
return db.campaignPerformanceReports;
},
},
};
如您所见,我在解析器中自定义了Device
枚举的值。
db.ts
:带有数据的虚假数据库
enum Device {
UNKNOWN = 'Other',
DESKTOP = 'Computers',
HIGH_END_MOBILE = 'Mobile devices with full browsers',
TABLET = 'Tablets with full browsers',
CONNECTED_TV = 'Devices streaming video content to TV screens',
}
export const db = {
campaignPerformanceReports: [
{
campaignId: 1,
campaignNme: 'test',
device: Device.DESKTOP,
},
],
};
我还为此进行了集成测试:
test.only('should query campaign performance reports correctly with executable graphql schema', async () => {
const schema = makeExecutableSchema({ typeDefs, resolvers });
console.log(printSchema(schema));
const server: ApolloServerBase = new ApolloServer({ schema, context: { db } });
const { query }: ApolloServerTestClient = createTestClient(server);
const res: GraphQLResponse = await query({ query: Q.campaignPerformanceReports });
expect(res).toMatchInlineSnapshot(`
Object {
"data": Object {
"campaignPerformanceReports": Array [
Object {
"campaignId": "1",
"campaignNme": "test",
"device": "DESKTOP",
},
],
},
"errors": undefined,
"extensions": undefined,
"http": Object {
"headers": Headers {
Symbol(map): Object {},
},
},
}
`);
});
如您所见,快照测试的结果。 device
字段的值仍为“ DESKTOP” ,我希望该值应为“计算机”
依赖版本:
"apollo-server": "^2.9.3",
"apollo-server-express": "^2.9.3",
"graphql": "^14.5.4",
最小存储库:https://github.com/mrdulin/apollo-graphql-tutorial/tree/master/src/custom-scalar-and-enum
答案 0 :(得分:2)
您为GraphQL枚举指定的内部值就是-内部。 documentation中对此进行了说明:
这些根本不会更改公共API ,但是它们确实允许您在解析程序中使用该值而不是架构值
如果将枚举值DESKTOP
映射到内部值Computers
,则只会影响解析程序的行为。具体来说:
Device
的参数,并且该参数传递的值为DESKTOP
,则实际传递给解析器函数的值为Computers
。DESKTOP
,则需要返回Computers
。例如,一个如下所示的模式:
type Query {
someQuery(device: Device!): Device!
}
如果您不指定内部值,我们的解析器将像这样工作:
function (parent, args) {
console.log(args.device) // "DESKTOP"
return 'DESKTOP'
}
如果执行指定内部值,则解析器如下所示:
function (parent, args) {
console.log(args.device) // "Computers"
return 'Computers'
}
解析器是唯一受每个枚举值的内部值影响的对象。 不更改的内容:
{ someQuery(device: DESKTOP) }
Device
的变量将始终写为"DESKTOP"
。注意:尽管该问题专门针对Apollo Server,但以上内容也适用于普通GraphQL.js。例如,这个枚举
const DeviceEnum = new GraphQLEnumType({
name: 'Device',
values: {
UNKNOWN: { value: 'Other' },
DESKTOP: { value: 'Computers' },
HIGH_END_MOBILE: { value: 'Mobile devices with full browsers' },
TABLET: { value: 'Tablets with full browsers' },
CONNECTED_TV: { value: 'Devices streaming video content to TV screens' },
}
})
仍然会如上所述。