Using Union on TYK UDG with REST Datasource

Hi guys, can UDG use Union type in the schema as the result of a query?
I’m using REST datasources here… so no additional resolver logic can be added
If im using GQL datasource can UDG resolve this?

type Query {
  getUser(id:Int):UserUnion
}
union UserUnion = User | CustomError


type CustomError{
  code: String
  message: String
}

type User{
  id:Int
  name:String
}

When I tried it , It does not resolve properly

I am checking this and will get back to you

Hey @midnight

so I did a few simple checks on my local Tyk instance and I was able to get union to work. And it should work for you as well in theory.
It might be a matter of connecting the datasources right. In your schema - where are the datasources connected exactly? You definitely need to have one connected to getUser root field, right? Did you connect anything else anywhere?

And one more question to make sure I can fully replicate your use case - the data source that you connect to getUser root field returns what exactly? I mean what’s the response body for status code 200 OK and what’s the response body in case of an error?

to make things clearer this is my last attempt query (the image above is outdated):

and this is the response from log

Debug
/data (afterFetchHook.OnData): {“user”:{“id”:1,“name”:“Bob”,“status”:“PENDING”,“accessories”:[“A”,“B”,“C”]}}

My datasource is connected to a local rest endpoint with this configuration

response in case of error:

/data (afterFetchHook.OnData): {“error”:{“code”:“ERR_01”,“message”:“some error”}}

Also tried these response , and still does not work
200 ok
/data (afterFetchHook.OnData): {“id”:1,“name”:“Bob”,“status”:“PENDING”,“accessories”:[“A”,“B”,“C”]}

error
/data (afterFetchHook.OnData): {“code”:“ERR_01”,“message”:“some error”}

Can you share your test data response and API configs?

Thanks for sending back the details. What I checked is not relevant in this situation - I used GQL as a data source, which worked fine, but it’s a different thing. I now replicated your exact example and I see the same issue as you do. I’ll create a ticket in our backlog and we’ll take a look at it - it looks like it’s something with the GQL engine, it gets all the responses from the upstream data sources but somehow “gets confused” on where to put the parsed information.

Before we fix this, you could try to use a workaround. Instead of defining response as a union, just move the error into User type like this:

type Query {
  getUser(id:Int): User
}

type CustomError{
  code: String
  message: String
}

type User{
  id:Int
  name:String
  error: CustomError
}

Then your getUser query root would get the data source as: http://data.com/users/{{.arguments.id}} and you’d have to connect a data source to error field on type User as well as http://data.com/users/{{.object.id}}.

I’ve created an issue in our GitHub so you can check the status going forward: UDG does not handle union as query result · Issue #4974 · TykTechnologies/tyk · GitHub

@agata-wit
I don’t know if this is another bug or the same , but I also find inconsistent behavior on union when I tried TYK UDG with GraphQL datasource,

image

LOG

2023-04-26 14:27:50 time="Apr 26 07:27:50" level=debug msg="/data (beforeFetchHook): {"method":"POST","url":"http://host.docker.internal:9001/query","header":{"X-Request-Id":["a8d2f0b1-89eb-4217-b465-242b61b9682d"],"X-User-Id":["user1"]},**"body":{"query":"mutation($updateInput: [CartUpdateItemInput!]!){cartUpdateItems(inputs: $updateInput){__typename ... on CartItem {id qty notes} ... on CartUpdateItemError }}"** ,"variables":{"updateInput":[{"qty":30,"itemId":"3c335965-9032-4f42-aa55-29c5e16d5526"},{"itemId":"a99582e0-970a-4906-9865-a390f86e2ff7","notes":"halo100"},{"itemId":"a99582e0-970a-4906-9865-a390f86e2ff7X","notes":"halo3"}]}}}" api_id=UDGStg api_name=UDGStg mw=GraphQLMiddleware org_id=1 origin=172.26.0.1 path=[47 100 97 116 97] 2023-04-26 14:27:50 time="Apr 26 07:27:50" level=debug msg="/data (afterFetchHook.OnData): null" api_id=UDGStg api_name=UDGStg mw=GraphQLMiddleware org_id=1 origin=172.26.0.1 path=[47 100 97 116 97] single_flight=false

2023-04-26 14:27:50 time="Apr 26 07:27:50" level=debug msg="/data (afterFetchHook.OnError): {"message":"Expected {, found }","locations":[{"line":1,"column":156}],"extensions":{"code":"GRAPHQL_PARSE_FAILED"}}" api_id=UDGStg api_name=UDGStg mw=GraphQLMiddleware org_id=1 origin=172.26.0.1 path=[47 100 97 116 97] single_flight=false

There are some field query that is not forwarded

“body”:{“query”:“mutation($updateInput: [CartUpdateItemInput!]!){cartUpdateItems(inputs: $updateInput){__typename … on CartItem {id qty notes} … on CartUpdateItemError }}”

Actual query


mutation updateItems($updateInput: [CartUpdateItemInput!]!) {
  cartUpdateItems(inputs: $updateInput) {
    __typename
    ... on CartItem {
      id
      qty
      notes
    }
    ... on CartUpdateItemError {
      itemId
      reason
    }
  }
}

When trying to service directly:
image

I think it’s time to summon higher engineering power :slight_smile: Let me reach out to the development squad directly and involve them in this conversation.