Sorry for the lenghty question, but it explains it best (you can try for yourself).
Given following docker-compose.yml:
version: '3.7'
services:
zero:
command: dgraph zero --my=zero:5080
image: dgraph/dgraph:v20.11.1
volumes:
- bug-dgraph:/dgraph:rw
dgraph:
command: dgraph alpha --my=dgraph:7080 --zero=zero:5080 --graphql_lambda_url=http://remote:8686/graphql-worker --whitelist=0.0.0.0/0
image: dgraph/dgraph:v20.11.1
ports:
- published: 8080
target: 8080
volumes:
- bug-dgraph:/dgraph:rw
remote:
image: alpine
command: ["/bin/sh","-c", 'while true; do echo -e "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Type: application/json\r\n\r\n{\"code\":100,\"message\":\"OK\",\"user\":{\"login\":\"john\",\"tenant\":{\"name\":\"NoName\"}}}" | nc -vl -p 8686 ; done']
schema:
image: curlimages/curl:7.75.0
volumes:
- garden-dgraph:/dgraph:rw
command: ["-v", "-X", "POST", "http://dgraph:8080/admin/schema","--data-binary","@schema.graphql"]
volumes:
- ./schema.graphql:/schema.graphql:ro
volumes:
bug-dgraph: {}
and following schema.graphql:
interface Event {
id: ID!
created_at: DateTime!
name: String! @search(by: [hash])
comment: String
created_by: User!
}
type TenantCreatedEvent implements Event {
tenant: Tenant!
tenant_name: String!
}
type TenantModifiedEvent implements Event {
Atenant: Tenant!
tenant_name: String!
}
type Tenant {
id: ID!
name: String! @search(by: [hash])
}
type User @secret(field:"password") {
login: String! @id @search(by: [hash])
first_name: String! @search(by: [hash])
last_name: String! @search(by: [hash])
tenant: Tenant
}
type UserPayload @remote {
status: Boolean!
code: Int!
message: String
error: String
user: User
}
type EmailVerificationPayload @remote {
status: Boolean!
code: Int!
message: String
error: String
user: User
}
type ResponsePayload @remote {
status: Boolean!
code: Int!
error: String
message: String
}
type Query {
verifyEmail(email:String!,code:String!): EmailVerificationPayload @lambda
}
# Dgraph.Authorization {"VerificationKey":"my_secret","Header":"X-Auth-Token","Namespace":"localhost","Algo":"HS256"}
when running it:
docker-compose up -d; sleep 10; docker-compose up
(where sleep is to wait for graphql endpoint readiness, then another docker-compose up for POSTing the new schema)
and then querying with insomnia for:
{
verifyEmail(email:"test",code:"test") {
code
error
message
user {
login
tenant {
name
}
}
}
}
I get following result:
{
"data": {
"verifyEmail": {
"code": 100,
"error": null,
"message": "OK",
"user": {
"login": "john",
"tenant": {
"name": "NoName"
}
}
}
}
Then when changing Atenant to tenant in TenantModifiedEvent and reloading the schema (with docker-compose up -d) and repeating the query I get:
{
"data": {
"verifyEmail": {
"code": 100,
"error": null,
"message": "OK",
"user": {
"login": "john",
"tenant": null
}
}
}
}
So I have 2 questions:
- Can I use the predicates with the same name (tenant) in different types implementing common interface? (I guess not)
- Why in the above examples the User.tenant is affected (returns null) when two other unrelated types implement predicates with the same name? I consider this as a bug.
Update: I experience similar unwanted side effect when using union instead of interface