Component(s)
cli
Component version
0.129.3
wgc version
0.129.3
controlplane version
N/A
router version
N/A
What happened?
Description
Given two schemas:
- One that use the
@inaccessible
- One that defines a directive that can be used on fields (e.g.
@dateFormat)
The execution config generated with wgc does not include the @dateFormat directive definition in the graphqlClientSchema (it is part of the graphqlSchema though).
The result is that any use of the directive @dateFormat in a query is rejected by the validation by Cosmo Router.
Note: if no schema uses @inaccessible, then the issue cannot be reproduced.
Steps to Reproduce
File inaccessible.graphqls:
extend schema
@link(
url: "https://specs.apollo.dev/federation/v2.3"
import: ["@key", "@inaccessible"]
)
type Query {
product(upc: String!): Product
}
type Product @key(fields: "upc") {
upc: String!
name: String!
"""
Private field. Presence of @inaccessible forces Cosmo to emit
engineConfig.graphqlClientSchema (client-facing schema).
"""
privateId: ID! @inaccessible
}
File runtime-directive.graphqls:
extend schema
@link(
url: "https://specs.apollo.dev/federation/v2.3"
import: ["@shareable", "@composeDirective"]
)
@link(url: "https://example.com/mytool/v1.0", import: ["@dateFormat"])
@composeDirective(name: "@dateFormat")
"""
Executable directive used in queries to format Date fields.
"""
directive @dateFormat(format: DateFormat! = ISO8601) on FIELD
enum DateFormat {
ISO8601
ISO8601_DATE_ONLY
DD_MMM_YYYY
}
"""
Date type, string value, supports the @dateFormat directive.
"""
scalar Date
type Query {
createdAt: Date @shareable
}
File: graph.yaml:
version: 1
subgraphs:
- name: inaccessible
routing_url: http://localhost:4001/graphql
schema:
file: ./inaccessible.graphqls
- name: runtime-directive
routing_url: http://localhost:4002/graphql
schema:
file: ./runtime-directive.graphqls
Then run:
npx -y wgc@latest router compose -i graph.yaml -o execution-config.json
Then inspect the generated execution-config.json.
Expected Result
I expect the @dateFormat to be accepted by the validation by Cosmo Router.
@dateFormat should be part of .engineConfig.graphqlClientSchema.
Actual Result
Cosmo Router rejects any use of @dateFormat in the query.
@dateFormat is not be part of .engineConfig.graphqlClientSchema.
Environment information
Environment
OS: darwin, linux
Package Manager: npm
Compiler(if manually compiled): node 22
Router configuration
Router execution config
{
"engineConfig": {
"defaultFlushInterval": "500",
"datasourceConfigurations": [
{
"kind": "GRAPHQL",
"rootNodes": [
{
"typeName": "Query",
"fieldNames": [
"product"
]
},
{
"typeName": "Product",
"fieldNames": [
"upc",
"name",
"privateId"
]
}
],
"overrideFieldPathFromAlias": true,
"customGraphql": {
"fetch": {
"url": {
"staticVariableContent": "http://localhost:4001/graphql"
},
"method": "POST",
"body": {},
"baseUrl": {},
"path": {}
},
"subscription": {
"enabled": true,
"url": {
"staticVariableContent": "http://localhost:4001/graphql"
},
"protocol": "GRAPHQL_SUBSCRIPTION_PROTOCOL_WS",
"websocketSubprotocol": "GRAPHQL_WEBSOCKET_SUBPROTOCOL_AUTO"
},
"federation": {
"enabled": true,
"serviceSdl": "extend schema\n @link(\n url: \"https://specs.apollo.dev/federation/v2.3\"\n import: [\"@key\", \"@inaccessible\"]\n )\n\ntype Query {\n product(upc: String!): Product\n}\n\ntype Product @key(fields: \"upc\") {\n upc: String!\n name: String!\n \"\"\"\n Private field. Presence of @inaccessible forces Cosmo to emit\n engineConfig.graphqlClientSchema (client-facing schema).\n \"\"\"\n privateId: ID! @inaccessible\n}\n"
},
"upstreamSchema": {
"key": "2959cab65563e3fc8d74362d3da513b0b80f84bb"
}
},
"requestTimeoutSeconds": "10",
"id": "0",
"keys": [
{
"typeName": "Product",
"selectionSet": "upc"
}
]
},
{
"kind": "GRAPHQL",
"rootNodes": [
{
"typeName": "Query",
"fieldNames": [
"createdAt"
]
}
],
"overrideFieldPathFromAlias": true,
"customGraphql": {
"fetch": {
"url": {
"staticVariableContent": "http://localhost:4002/graphql"
},
"method": "POST",
"body": {},
"baseUrl": {},
"path": {}
},
"subscription": {
"enabled": true,
"url": {
"staticVariableContent": "http://localhost:4002/graphql"
},
"protocol": "GRAPHQL_SUBSCRIPTION_PROTOCOL_WS",
"websocketSubprotocol": "GRAPHQL_WEBSOCKET_SUBPROTOCOL_AUTO"
},
"federation": {
"enabled": true,
"serviceSdl": "extend schema\n @link(\n url: \"https://specs.apollo.dev/federation/v2.3\"\n import: [\"@shareable\", \"@composeDirective\"]\n )\n @link(url: \"https://example.com/mytool/v1.0\", import: [\"@dateFormat\"])\n @composeDirective(name: \"@dateFormat\")\n\n\"\"\"\nExecutable directive used in queries to format Date fields.\n\"\"\"\ndirective @dateFormat(format: DateFormat! = ISO8601) on FIELD\n\nenum DateFormat {\n ISO8601\n ISO8601_DATE_ONLY\n DD_MMM_YYYY\n}\n\n\"\"\"\nDate type, string value, supports the @dateFormat directive.\n\"\"\"\nscalar Date\n\ntype Query {\n createdAt: Date @shareable\n}\n"
},
"upstreamSchema": {
"key": "0d18c8697c45acb28c452042e2c7a9c1da88a32a"
}
},
"requestTimeoutSeconds": "10",
"id": "1"
}
],
"fieldConfigurations": [
{
"typeName": "Query",
"fieldName": "product",
"argumentsConfiguration": [
{
"name": "upc",
"sourceType": "FIELD_ARGUMENT"
}
]
}
],
"graphqlSchema": "schema {\n query: Query\n}\n\ndirective @inaccessible on ARGUMENT_DEFINITION | ENUM | ENUM_VALUE | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | INPUT_OBJECT | INTERFACE | OBJECT | SCALAR | UNION\n\n\"\"\"Executable directive used in queries to format Date fields.\"\"\"\ndirective @dateFormat(format: DateFormat! = ISO8601) on FIELD\n\ntype Query {\n product(upc: String!): Product\n createdAt: Date\n}\n\ntype Product {\n upc: String!\n name: String!\n \"\"\"\n Private field. Presence of @inaccessible forces Cosmo to emit\n engineConfig.graphqlClientSchema (client-facing schema).\n \"\"\"\n privateId: ID! @inaccessible\n}\n\nenum DateFormat {\n ISO8601\n ISO8601_DATE_ONLY\n DD_MMM_YYYY\n}\n\n\"\"\"Date type, string value, supports the @dateFormat directive.\"\"\"\nscalar Date",
"stringStorage": {
"2959cab65563e3fc8d74362d3da513b0b80f84bb": "schema {\n query: Query\n}\n\ndirective @inaccessible on ARGUMENT_DEFINITION | ENUM | ENUM_VALUE | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | INPUT_OBJECT | INTERFACE | OBJECT | SCALAR | UNION\n\ndirective @key(fields: openfed__FieldSet!, resolvable: Boolean = true) repeatable on INTERFACE | OBJECT\n\ndirective @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA\n\ntype Product @key(fields: \"upc\") {\n name: String!\n \"\"\"\n Private field. Presence of @inaccessible forces Cosmo to emit\n engineConfig.graphqlClientSchema (client-facing schema).\n \"\"\"\n privateId: ID! @inaccessible\n upc: String!\n}\n\ntype Query {\n product(upc: String!): Product\n}\n\nscalar link__Import\n\nenum link__Purpose {\n EXECUTION\n SECURITY\n}\n\nscalar openfed__FieldSet",
"0d18c8697c45acb28c452042e2c7a9c1da88a32a": "schema {\n query: Query\n}\n\ndirective @composeDirective(name: String!) repeatable on SCHEMA\n\n\"\"\"Executable directive used in queries to format Date fields.\"\"\"\ndirective @dateFormat(format: DateFormat! = ISO8601) on FIELD\n\ndirective @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA\n\ndirective @shareable repeatable on FIELD_DEFINITION | OBJECT\n\n\"\"\"Date type, string value, supports the @dateFormat directive.\"\"\"\nscalar Date\n\nenum DateFormat {\n DD_MMM_YYYY\n ISO8601\n ISO8601_DATE_ONLY\n}\n\ntype Query {\n createdAt: Date @shareable\n}\n\nscalar link__Import\n\nenum link__Purpose {\n EXECUTION\n SECURITY\n}"
},
"graphqlClientSchema": "schema {\n query: Query\n}\n\ntype Query {\n product(upc: String!): Product\n createdAt: Date\n}\n\ntype Product {\n upc: String!\n name: String!\n}\n\nenum DateFormat {\n ISO8601\n ISO8601_DATE_ONLY\n DD_MMM_YYYY\n}\n\n\"\"\"Date type, string value, supports the @dateFormat directive.\"\"\"\nscalar Date"
},
"version": "00000000-0000-0000-0000-000000000000",
"subgraphs": [
{
"id": "0",
"name": "inaccessible",
"routingUrl": "http://localhost:4001/graphql"
},
{
"id": "1",
"name": "runtime-directive",
"routingUrl": "http://localhost:4002/graphql"
}
],
"featureFlagConfigs": {},
"compatibilityVersion": "1:0.63.1"
}
Log output
Additional context
No response
Component(s)
cli
Component version
0.129.3
wgc version
0.129.3
controlplane version
N/A
router version
N/A
What happened?
Description
Given two schemas:
@inaccessible@dateFormat)The execution config generated with
wgcdoes not include the@dateFormatdirective definition in thegraphqlClientSchema(it is part of thegraphqlSchemathough).The result is that any use of the directive
@dateFormatin a query is rejected by the validation by Cosmo Router.Note: if no schema uses
@inaccessible, then the issue cannot be reproduced.Steps to Reproduce
File
inaccessible.graphqls:File
runtime-directive.graphqls:File:
graph.yaml:Then run:
Then inspect the generated
execution-config.json.Expected Result
I expect the
@dateFormatto be accepted by the validation by Cosmo Router.@dateFormatshould be part of.engineConfig.graphqlClientSchema.Actual Result
Cosmo Router rejects any use of
@dateFormatin the query.@dateFormatis not be part of.engineConfig.graphqlClientSchema.Environment information
Environment
OS: darwin, linux
Package Manager: npm
Compiler(if manually compiled): node 22
Router configuration
Router execution config
{ "engineConfig": { "defaultFlushInterval": "500", "datasourceConfigurations": [ { "kind": "GRAPHQL", "rootNodes": [ { "typeName": "Query", "fieldNames": [ "product" ] }, { "typeName": "Product", "fieldNames": [ "upc", "name", "privateId" ] } ], "overrideFieldPathFromAlias": true, "customGraphql": { "fetch": { "url": { "staticVariableContent": "http://localhost:4001/graphql" }, "method": "POST", "body": {}, "baseUrl": {}, "path": {} }, "subscription": { "enabled": true, "url": { "staticVariableContent": "http://localhost:4001/graphql" }, "protocol": "GRAPHQL_SUBSCRIPTION_PROTOCOL_WS", "websocketSubprotocol": "GRAPHQL_WEBSOCKET_SUBPROTOCOL_AUTO" }, "federation": { "enabled": true, "serviceSdl": "extend schema\n @link(\n url: \"https://specs.apollo.dev/federation/v2.3\"\n import: [\"@key\", \"@inaccessible\"]\n )\n\ntype Query {\n product(upc: String!): Product\n}\n\ntype Product @key(fields: \"upc\") {\n upc: String!\n name: String!\n \"\"\"\n Private field. Presence of @inaccessible forces Cosmo to emit\n engineConfig.graphqlClientSchema (client-facing schema).\n \"\"\"\n privateId: ID! @inaccessible\n}\n" }, "upstreamSchema": { "key": "2959cab65563e3fc8d74362d3da513b0b80f84bb" } }, "requestTimeoutSeconds": "10", "id": "0", "keys": [ { "typeName": "Product", "selectionSet": "upc" } ] }, { "kind": "GRAPHQL", "rootNodes": [ { "typeName": "Query", "fieldNames": [ "createdAt" ] } ], "overrideFieldPathFromAlias": true, "customGraphql": { "fetch": { "url": { "staticVariableContent": "http://localhost:4002/graphql" }, "method": "POST", "body": {}, "baseUrl": {}, "path": {} }, "subscription": { "enabled": true, "url": { "staticVariableContent": "http://localhost:4002/graphql" }, "protocol": "GRAPHQL_SUBSCRIPTION_PROTOCOL_WS", "websocketSubprotocol": "GRAPHQL_WEBSOCKET_SUBPROTOCOL_AUTO" }, "federation": { "enabled": true, "serviceSdl": "extend schema\n @link(\n url: \"https://specs.apollo.dev/federation/v2.3\"\n import: [\"@shareable\", \"@composeDirective\"]\n )\n @link(url: \"https://example.com/mytool/v1.0\", import: [\"@dateFormat\"])\n @composeDirective(name: \"@dateFormat\")\n\n\"\"\"\nExecutable directive used in queries to format Date fields.\n\"\"\"\ndirective @dateFormat(format: DateFormat! = ISO8601) on FIELD\n\nenum DateFormat {\n ISO8601\n ISO8601_DATE_ONLY\n DD_MMM_YYYY\n}\n\n\"\"\"\nDate type, string value, supports the @dateFormat directive.\n\"\"\"\nscalar Date\n\ntype Query {\n createdAt: Date @shareable\n}\n" }, "upstreamSchema": { "key": "0d18c8697c45acb28c452042e2c7a9c1da88a32a" } }, "requestTimeoutSeconds": "10", "id": "1" } ], "fieldConfigurations": [ { "typeName": "Query", "fieldName": "product", "argumentsConfiguration": [ { "name": "upc", "sourceType": "FIELD_ARGUMENT" } ] } ], "graphqlSchema": "schema {\n query: Query\n}\n\ndirective @inaccessible on ARGUMENT_DEFINITION | ENUM | ENUM_VALUE | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | INPUT_OBJECT | INTERFACE | OBJECT | SCALAR | UNION\n\n\"\"\"Executable directive used in queries to format Date fields.\"\"\"\ndirective @dateFormat(format: DateFormat! = ISO8601) on FIELD\n\ntype Query {\n product(upc: String!): Product\n createdAt: Date\n}\n\ntype Product {\n upc: String!\n name: String!\n \"\"\"\n Private field. Presence of @inaccessible forces Cosmo to emit\n engineConfig.graphqlClientSchema (client-facing schema).\n \"\"\"\n privateId: ID! @inaccessible\n}\n\nenum DateFormat {\n ISO8601\n ISO8601_DATE_ONLY\n DD_MMM_YYYY\n}\n\n\"\"\"Date type, string value, supports the @dateFormat directive.\"\"\"\nscalar Date", "stringStorage": { "2959cab65563e3fc8d74362d3da513b0b80f84bb": "schema {\n query: Query\n}\n\ndirective @inaccessible on ARGUMENT_DEFINITION | ENUM | ENUM_VALUE | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | INPUT_OBJECT | INTERFACE | OBJECT | SCALAR | UNION\n\ndirective @key(fields: openfed__FieldSet!, resolvable: Boolean = true) repeatable on INTERFACE | OBJECT\n\ndirective @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA\n\ntype Product @key(fields: \"upc\") {\n name: String!\n \"\"\"\n Private field. Presence of @inaccessible forces Cosmo to emit\n engineConfig.graphqlClientSchema (client-facing schema).\n \"\"\"\n privateId: ID! @inaccessible\n upc: String!\n}\n\ntype Query {\n product(upc: String!): Product\n}\n\nscalar link__Import\n\nenum link__Purpose {\n EXECUTION\n SECURITY\n}\n\nscalar openfed__FieldSet", "0d18c8697c45acb28c452042e2c7a9c1da88a32a": "schema {\n query: Query\n}\n\ndirective @composeDirective(name: String!) repeatable on SCHEMA\n\n\"\"\"Executable directive used in queries to format Date fields.\"\"\"\ndirective @dateFormat(format: DateFormat! = ISO8601) on FIELD\n\ndirective @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA\n\ndirective @shareable repeatable on FIELD_DEFINITION | OBJECT\n\n\"\"\"Date type, string value, supports the @dateFormat directive.\"\"\"\nscalar Date\n\nenum DateFormat {\n DD_MMM_YYYY\n ISO8601\n ISO8601_DATE_ONLY\n}\n\ntype Query {\n createdAt: Date @shareable\n}\n\nscalar link__Import\n\nenum link__Purpose {\n EXECUTION\n SECURITY\n}" }, "graphqlClientSchema": "schema {\n query: Query\n}\n\ntype Query {\n product(upc: String!): Product\n createdAt: Date\n}\n\ntype Product {\n upc: String!\n name: String!\n}\n\nenum DateFormat {\n ISO8601\n ISO8601_DATE_ONLY\n DD_MMM_YYYY\n}\n\n\"\"\"Date type, string value, supports the @dateFormat directive.\"\"\"\nscalar Date" }, "version": "00000000-0000-0000-0000-000000000000", "subgraphs": [ { "id": "0", "name": "inaccessible", "routingUrl": "http://localhost:4001/graphql" }, { "id": "1", "name": "runtime-directive", "routingUrl": "http://localhost:4002/graphql" } ], "featureFlagConfigs": {}, "compatibilityVersion": "1:0.63.1" }Log output
Additional context
No response