Hello @agata-wit .
Thanks for answering me.
Yes, we create a new scalar; let me send you the API definition.
{
"name": "",
"slug": "",
"api_id": "",
"org_id": "",
"active": true,
"use_openid": false,
"use_basic_auth": false,
"use_keyless": true,
"auth_configs": {
"basic": {
"auth_header_name": ""
}
},
"graphql": {
"enabled": true,
"engine": {
"field_configs": [],
"data_sources": []
},
"type_field_configurations": [],
"execution_mode": "subgraph",
"proxy": {
"auth_headers": {}
},
"subgraph": {
"sdl": "directive @specifiedBy( url: String!) on SCALAR scalar JSON type Asset { name: JSON sources: [Source!]! description: JSON key: String tags: [String!] } type AttributeField { name: String! attributeType: AttributeTypeField! label: JSON isRequired: Boolean attributeConstraint: String } type AttributeTypeField { name: AttributeTypeNames! values: JSON referenceId: String elementType: BaseAttributeTypeField } enum AttributeTypeNames { text ltext boolean enum number date time reference set } type BaseAttributeTypeField { name: AttributeTypeNames! values: JSON referenceId: String } input BaseAttributeTypeInput { name: AttributeTypeNames! values: JSON = null referenceId: String = null } type Category { uid: Int! name: JSON companyId: Int! externalId: String! orderHint: String! key: String description: JSON custom: CustomField assets: [Asset!] slug: JSON fullUrl: JSON } type Channel { name: JSON roles: [String!]! description: JSON externalId: String key: String version: Int } enum ChannelRoles { InventorySupply ProductDistribution OrderExport OrderImport Primary } enum ChannelUpdateActions { ChangeDescription SetRoles AddRoles RemoveRoles } type CollectionExternalData { categoryExternalId: String! productTypeExternalIds: [String!]! inventoryExternalIds: [String!]! channelExternalIds: [String!]! } type CollectionProduct { name: JSON _id: String! description: JSON externalId: String key: String uid: Int companyId: Int categories: [Int!] variants: [ProductVariant!] publish: Boolean slug: JSON } type CustomField { customType: String! fields: JSON } type CustomJSON { key: String! container: String! value: String! externalId: String version: Int } type Dimensions { width: Int! height: Int! } type Image { url: String! dimensions: Dimensions! label: String! } input InputAsset { name: JSON sources: [InputSource!]! description: JSON = null key: String = null tags: [String!] = null } input InputAttribute { name: String! attributeType: InputAttributeType! label: JSON isRequired: Boolean = false attributeConstraint: String = \"SameForAll\" } input InputAttributeType { name: AttributeTypeNames! values: JSON = null referenceId: String = null elementType: BaseAttributeTypeInput = null } input InputChannel { name: JSON roles: [ChannelRoles!]! description: JSON externalId: String = null version: Int = 1 } input InputChannelActions { key: String! actions: ChannelUpdateActions! newValue: UpdateChannel version: Int! } input InputCustomJSON { key: String! container: String! value: String! version: Int = 1 } input InputDimensions { width: Int! height: Int! } input InputImage { url: String! dimensions: InputDimensions! label: String! } input InputInventory { key: String! sku: String! supplyChannel: String = null quantityOnStock: Int = 0 } input InputProduct { name: JSON productTypeId: String! description: JSON categories: [Int!] = null variants: [InputProductVariant!] = null publish: Boolean = false slug: JSON } input InputProductType { name: String! description: String! attributes: [InputAttribute!]! externalId: String = null } input InputProductTypeActions { action: ProductTypeUpdateActions! key: String! version: Int! newValues: UpdateProductType } input InputProductVariant { key: String! sku: String! attributes: JSON = null images: [InputImage!] = null assets: [InputAsset!] = null } input InputSource { uri: String! key: String = null } type Inventory { key: String! sku: String! _id: String! supplyChannel: String quantityOnStock: Int version: Int externalId: String } enum InventoryUpdateActions { changeQuantity setSupplyChannel } input InventoryUpdatePayload { actions: [InventoryUpdateActions!]! payload: UpdatePayload! } type Mutation { importProductById(uid: Int!, productTypeKey: String!): CollectionProduct addProduct(product: InputProduct!, productTypeKey: String!): CollectionProduct addProductType(productType: InputProductType!): ProductType updateProductType(productType: InputProductTypeActions!): ProductType deleteProductType(key: String!): String addCustomJSON(customJSON: InputCustomJSON!): CustomJSON updateCustomJSON(customJSON: InputCustomJSON!): CustomJSON deleteCustomJSON(key: String!): Boolean! addInventory(inventory: InputInventory!): Inventory deleteInventory(key: String!): Boolean! updateInventory(key: String!, payload: InventoryUpdatePayload!): Inventory addChannel(channel: InputChannel!): Channel updateChannel(channel: InputChannelActions!): Channel deleteChannel(key: String!): Boolean } type ProductType { name: String! description: String! attributes: [AttributeField!]! _id: String! externalId: String key: String } enum ProductTypeUpdateActions { changeDescription addAttributeDefinition removeAttributeDefinition changeAttributeConstraint } type ProductVariant { key: String! sku: String! attributes: JSON images: [Image!] assets: [Asset!] } type Source { uri: String! key: String } input UpdateChannel { name: JSON description: JSON key: String roles: [ChannelRoles!] } input UpdatePayload { quantity: Int channelId: String } input UpdateProductType { name: String key: String description: String constraint: String attributes: InputAttribute } type Query { category(slug: String!, companyId: Int = 1, language: String = \"en\"): Category categories(slug: String = null, name: String = null, companyId: Int = 1, language: String = \"en\"): [Category!]! getAllBySlug(slug: String!, locale: String! = \"es\"): CollectionExternalData! productType(name: String!): ProductType customJSON(key: String!): CustomJSON getProduct(uid: Int!, companyId: Int = 1): CollectionProduct getProducts(companyId: Int = 1): [CollectionProduct!]! inventory(key: String!): Inventory channel(key: String!): Channel channels: [Channel!] } type Mutation { importProductById(uid: Int!, productTypeKey: String!): CollectionProduct addProduct(product: InputProduct!, productTypeKey: String!): CollectionProduct addProductType(productType: InputProductType!): ProductType updateProductType(productType: InputProductTypeActions!): ProductType deleteProductType(key: String!): String addCustomJSON(customJSON: InputCustomJSON!): CustomJSON updateCustomJSON(customJSON: InputCustomJSON!): CustomJSON deleteCustomJSON(key: String!): Boolean! addInventory(inventory: InputInventory!): Inventory deleteInventory(key: String!): Boolean! updateInventory(key: String!, payload: InventoryUpdatePayload!): Inventory addChannel(channel: InputChannel!): Channel updateChannel(channel: InputChannelActions!): Channel deleteChannel(key: String!): Boolean }"
},
"version": "2",
"playground": {
"enabled": false,
"path": ""
},
"last_schema_update": "2022-07-12T15:34:44.408Z",
"schema": "directive @specifiedBy( url: String!) on SCALAR scalar JSON type Asset { name: JSON sources: [Source!]! description: JSON key: String tags: [String!] } type AttributeField { name: String! attributeType: AttributeTypeField! label: JSON isRequired: Boolean attributeConstraint: String } type AttributeTypeField { name: AttributeTypeNames! values: JSON referenceId: String elementType: BaseAttributeTypeField } enum AttributeTypeNames { text ltext boolean enum number date time reference set } type BaseAttributeTypeField { name: AttributeTypeNames! values: JSON referenceId: String } input BaseAttributeTypeInput { name: AttributeTypeNames! values: JSON = gull referenceId: String = null } type Category { uid: Int! name: JSON companyId: Int! externalId: String! orderHint: String! key: String description: JSON custom: CustomField assets: [Asset!] slug: JSON fullUrl: JSON } type Channel { name: JSON roles: [String!]! description: JSON externalId: String key: String version: Int } enum ChannelRoles { InventorySupply ProductDistribution OrderExport OrderImport Primary } enum ChannelUpdateActions { ChangeDescription SetRoles AddRoles RemoveRoles } type CollectionExternalData { categoryExternalId: String! productTypeExternalIds: [String!]! inventoryExternalIds: [String!]! channelExternalIds: [String!]! } type CollectionProduct { name: JSON _id: String! description: JSON externalId: String key: String uid: Int companyId: Int categories: [Int!] variants: [ProductVariant!] publish: Boolean slug: JSON } type CustomField { customType: String! fields: JSON } type CustomJSON { key: String! container: String! value: String! externalId: String version: Int } type Dimensions { width: Int! height: Int! } type Image { url: String! dimensions: Dimensions! label: String! } input InputAsset { name: JSON sources: [InputSource!]! description: JSON = null key: String = null tags: [String!] = null } input InputAttribute { name: String! attributeType: InputAttributeType! label: JSON isRequired: Boolean = false attributeConstraint: String = \"SameForAll\" } input InputAttributeType { name: AttributeTypeNames! values: JSON = null referenceId: String = null elementType: BaseAttributeTypeInput = null } input InputChannel { name: JSON roles: [ChannelRoles!]! description: JSON externalId: String = null version: Int = 1 } input InputChannelActions { key: String! actions: ChannelUpdateActions! newValue: UpdateChannel version: Int! } input InputCustomJSON { key: String! container: String! value: String! version: Int = 1 } input InputDimensions { width: Int! height: Int! } input InputImage { url: String! dimensions: InputDimensions! label: String! } input InputInventory { key: String! sku: String! supplyChannel: String = null quantityOnStock: Int = 0 } input InputProduct { name: JSON productTypeId: String! description: JSON categories: [Int!] = null variants: [InputProductVariant!] = null publish: Boolean = false slug: JSON } input InputProductType { name: String! description: String! attributes: [InputAttribute!]! externalId: String = null } input InputProductTypeActions { action: ProductTypeUpdateActions! key: String! version: Int! newValues: UpdateProductType } input InputProductVariant { key: String! sku: String! attributes: JSON = null images: [InputImage!] = null assets: [InputAsset!] = null } input InputSource { uri: String! key: String = null } type Inventory { key: String! sku: String! _id: String! supplyChannel: String quantityOnStock: Int version: Int externalId: String } enum InventoryUpdateActions { changeQuantity setSupplyChannel } input InventoryUpdatePayload { actions: [InventoryUpdateActions!]! payload: UpdatePayload! } type Mutation { importProductById(uid: Int!, productTypeKey: String!): CollectionProduct addProduct(product: InputProduct!, productTypeKey: String!): CollectionProduct addProductType(productType: InputProductType!): ProductType updateProductType(productType: InputProductTypeActions!): ProductType deleteProductType(key: String!): String addCustomJSON(customJSON: InputCustomJSON!): CustomJSON updateCustomJSON(customJSON: InputCustomJSON!): CustomJSON deleteCustomJSON(key: String!): Boolean! addInventory(inventory: InputInventory!): Inventory deleteInventory(key: String!): Boolean! updateInventory(key: String!, payload: InventoryUpdatePayload!): Inventory addChannel(channel: InputChannel!): Channel updateChannel(channel: InputChannelActions!): Channel deleteChannel(key: String!): Boolean } type ProductType { name: String! description: String! attributes: [AttributeField!]! _id: String! externalId: String key: String } enum ProductTypeUpdateActions { changeDescription addAttributeDefinition removeAttributeDefinition changeAttributeConstraint } type ProductVariant { key: String! sku: String! attributes: JSON images: [Image!] assets: [Asset!] } type Source { uri: String! key: String } input UpdateChannel { name: JSON description: JSON key: String roles: [ChannelRoles!] } input UpdatePayload { quantity: Int channelId: String } input UpdateProductType { name: String key: String description: String constraint: String attributes: InputAttribute } type Query { category(slug: String!, companyId: Int = 1, language: String = \"en\"): Category categories(slug: String = null, name: String = null, companyId: Int = 1, language: String = \"en\"): [Category!]! getAllBySlug(slug: String!, locale: String! = \"es\"): CollectionExternalData! productType(name: String!): ProductType customJSON(key: String!): CustomJSON getProduct(uid: Int!, companyId: Int = 1): CollectionProduct getProducts(companyId: Int = 1): [CollectionProduct!]! inventory(key: String!): Inventory channel(key: String!): Channel channels: [Channel!] } type Mutation { importProductById(uid: Int!, productTypeKey: String!): CollectionProduct addProduct(product: InputProduct!, productTypeKey: String!): CollectionProduct addProductType(productType: InputProductType!): ProductType updateProductType(productType: InputProductTypeActions!): ProductType deleteProductType(key: String!): String addCustomJSON(customJSON: InputCustomJSON!): CustomJSON updateCustomJSON(customJSON: InputCustomJSON!): CustomJSON deleteCustomJSON(key: String!): Boolean! addInventory(inventory: InputInventory!): Inventory deleteInventory(key: String!): Boolean! updateInventory(key: String!, payload: InventoryUpdatePayload!): Inventory addChannel(channel: InputChannel!): Channel updateChannel(channel: InputChannelActions!): Channel deleteChannel(key: String!): Boolean }"
},
"version_data": {
"not_versioned": true,
"versions": {
"Default": {
"name": "Default",
"use_extended_paths": true
}
}
},
"enable_batch_request_support": true,
"CORS": {
"enable": true,
"allowed_origins": [
"*"
],
"allowed_methods": ["GET", "POST", "OPTIONS"],
"allowed_headers": ["*"],
"exposed_headers": [],
"allow_credentials": false,
"max_age": 24,
"options_passthrough": false,
"debug": true
},
"proxy": {
"listen_path": "/service/",
"target_url": "http://localhost:8080/service",
"strip_listen_path": true
},
"internal": false
}
Our backend is written in python 3.10 using Fastapi and Strawberry.
We create the scalar in the following way.
JSON = strawberry.scalar(
NewType("JSON", object),
description="The `JSON` scalar type represents JSON values as specified by ECMA-404",
serialize=lambda v: v,
parse_value=lambda v: v,
)
Yes, when I query the service out of the gateway, it works as expected:
This is the answer when I query directly
{
"name": {
"en": "Test Óptico",
"es": "Test Óptico"
}
}
Using the gateway:
{
"name": null
},
Even when in Tyk’s log, I can see in debug mode the right answer I’m expecting.
I tested using scalar _Any
, and I got the same behavior, a null instead of the JSON
Regards.