Query interface

Hi!

I’ve defined an interface (Org) and implemented it (StorageOrg and LabOrg); all three of these types have Dgraph-generated queries but I’m unable to get any data back when using the “interface” query. Is there a limitation behind this? The functionality I was expecting was that querying using the “interface” query with an empty filter ({}) would return an unfiltered list of all of the implementations of the Org interface. Was this an incorrect assumption?

Best,
John

Hi @forstmeier,

Can you provide more information on how you were using the “interface” query ?
Interfaces in Graphql are useful when you want to return an object or set of objects, but those might be of several different types. By creating an Org interface and implementing it in StorageOrg and LabOrg, three graphql queries will be generated, queryOrg, queryStorageOrg, queryLabOrg.

In case you use the queryOrg query as follows,

query{
    queryOrg{
        id
        ...   // Any other predicates present in Org
    }
}

you should be able to get a list of all nodes which have type LabOrg or StorageOrg or any of the types which impelement interface Org .

Hi @rajas!

I was running this query:

{
	"query": "query QueryOrgs { queryOrg(filter: {}) { id, name, createdOn, updatedOn } }"
}

Running the query you provided also didn’t return any data.

Here’s a snippet of my schema:

interface Org {
	id: ID!
	name: String! @search(by: [hash])
	users: [User] @hasInverse(field: org)
	createdOn: DateTime!
	updatedOn: DateTime!
}

type LabOrg implements Org & Location @auth( ... ) {
	owner: OwnerOrg!
	specimens: [Specimen] @hasInverse(field: lab)
	plans: [Plan] @hasInverse(field: labs)
}

type StorageOrg implements Org & Location @auth( ... ) {
	owner: OwnerOrg!
	specimens: [Specimen] @hasInverse(field: storage)
	plans: [Plan] @hasInverse(field: storages)
}

The response that comes back is successful (200 status) and the body looks fine there’s just an empty array for { "data": { "queryOrg": [] } }.

Hi @forstmeier,

I have defined similar interfaces and types and I am able to get a list of all nodes with type LabOrg or StorageOrg in the output on querying with an empty filter.
I see that you are using @auth directive along with types. I suspect that the reason for Graphql returning an empty list is due to the querying user not satisfying the auth rule.

For more details regarding the @auth directive: https://dgraph.io/docs/graphql/authorization/directive/

Hey @rajas,

That was my assumption too but if I ran the queries on both the implementations, I was getting results with the same user I was using to query on the interface. The interface itself does not have an @auth directive since I was under the impression that there was not yet support for that. I’ll play around with the @auth definitions on all of the types/interfaces involved to see if maybe I’m missing something?

Best,
John

Hi @forstmeier

Could you please share the schema and a reproducible example with some mutations and queries that you are running?

Hey @pawan, here’s some of the resources you requested.

Current schema - this includes all of the @auth stuff I’ve included

Body of the first mutation I send (because I used the OwnerOrg ID as my multitenancy barrier):

{
	"query": "mutation AddOwnerOrgs($input: [AddOwnerOrgInput!]!) { addOwnerOrg(input: $input)  { ownerOrg { id } } }",
	"variables": {
		"input": [
			{
				"street": "street1",
				"city": "city1",
				"county": "count1",
				"state": "state1",
				"country": "usa",
				"zip": 11111,
				"name": "first owner org",
				"createdOn": "2006-01-02T15:04:05",
				"updatedOn": "2006-01-02T15:04:05"
			}
		]
	}
}

Body of the second mutation sent (this one includes the references to the ID generated by the mutation above:

{
	"query": "mutation AddStorageOrg($input: [AddStorageOrgInput!]!) { addStorageOrg(input: $input) { storageOrg { name } } }",
	"variables": {
		"input": [
			{
				"street": "street2",
				"city": "city2",
				"county": "county2",
				"state": "state2",
				"country": "usa",
				"zip": 22222,
				"name": "new storage org",
				"createdOn": "2020-01-02T15:04:05",
				"updatedOn": "2020-01-02T15:04:05",
				"owner": {
					"id": "ID_FROM_ABOVE"
				}
			}
		]
	}
}

The “interface” query I run (as per the recommendation from @rajas):

{
	"query": "query { queryOrg { id } } "
}

The result here is a 200 status response but no data. I’m able to use the generated queryStorageOrg with an empty filter and that pulls back the StorageOrg type that was added with the second mutation (as expected).

@pawan and @rajas, I’m continuing to experience this issue. I’ve also tested it out on a separate interface query that my schema generates (querySpecimen, also available in the link to the schema I posted in the prior message) but I can’t get it to return any data. I’m getting a 200 status back but "data": { "querySpecimen": [] } is the payload.

Basically, what seems to be happening is that querying on the interface types using the generated query is failing. I don’t have @auth defined on those interfaces because last I heard it was not supported yet - maybe that’s changed or is the core of my issue?

EDIT: I’m also just encountering errors in general now with queries that sort of work but the @auth definition I provided does not seem to actually be filtering properly - e.g. for queryOwnerOrg all OwnerOrg types are being returned, not just the ones that receive a request with a JWT containing a custom claim of orgID matching their own ID field. I feel like I’ve missed something on how the auth definitions should be working…

Hi @forstmeier,

Thanks for sharing more details about the schema. I was able to reproduce the issue you are facing about interface query returning an empty list.

Dgraph currently does not support @auth for interfaces and hence, an empty list is returned. There is an RFC for supporting @auth on interfaces and work would be carried out in next 2-4 weeks. You may find more details here

Were you facing this issue before. Can you share more details about the schema or examples in which you are facing these issues ?

@rajas okay, thanks! Perfect info on the coming support (although the link is broken it should be 9699 I believe in the path).

I hadn’t run into this issue directly since I hadn’t actually been testing/integrating the schema on those Types at that point.

I’m marking your comment as the solution so that anyone else who runs into this issue in the next 2-4 weeks can reference the same resources.

Hi @rajas, I just swung back through to that discussion link you mentioned in your last response and haven’t seen any movement on it and I skimmed through the most recent changelogs - any word on if this is under development?

Thanks for checking by. As you can see, the RFC received a few comments delaying its implementation. The issue is high on our priority list and should definitely be there in 20.11 version.

Tagging @minhaj to share any more updates.

1 Like

We will work on the RFC this week and it should be implemented in next couple of weeks hopefully. It is high priority for us also.

2 Likes

Hi @minhaj just touching base on this - I skimmed the most recent changelogs but didn’t see anything and wanted to see where things stood.

Hi @forstmeier, We will be taking up this from the next week hopefully.

1 Like

Hi @forstmeier,

The PR for enabling auth on querying interfaces has been merged into master. This feature should be there in 20.11 .
Reference : feat(GraphQL): Allow Query with Auth rules on Interfaces by minhaj-shakeel · Pull Request #6776 · dgraph-io/dgraph · GitHub

2 Likes