GraphQL multiple query or alternative

Hi,

I have this usecase that I need to output some user data, and if the user is admin then additional data should be outputted.

So how should I implement this: Can I do multiquery in DGraph? take output from query 1 and use it in query 2 in a single call?

Alternative which I have found is to first make a call, and check if user is admin, then do something like this: allowedPhones @include(if: $isAdmin) in 2. call.

But would be great if I can do all this in a single call.

:thinking:

type User {
	id: ID! 
	authId: String! @search(by:[exact]) 
	phone: String! @search(by:[exact,fulltext]) 
	email: String @search(by:[exact,fulltext]) 
	firstName: String! @search(by:[exact,fulltext]) 
	lastName: String! @search(by:[exact,fulltext]) 
	created: DateTime! 
	tags: [String] @search(by:[exact]) 
	companies: [UserRole] @hasInverse(field:user) 
        ...
}

type UserRole  {
	id: ID! 
	user: User! 
	company: Company! 
	role: Role! @search(by:[exact]) 
	created: DateTime! 
}

enum Role {
	ADMIN
	MANAGER
	USER
	GUEST
}

type Company  {
	id: ID! 
...
	users: [UserRole] @hasInverse(field:company) 
	allowedPhones: [String] @search(by:[exact]) 
}

Hey @zaiby,

Check out Role-based access control… seems to be exactly what you’re asking for: RBAC rules - GraphQL

Thanks for your reply, I’m not using auth in dgraph, it got complicated very quickly (Users can have different roles, on different companies.). And I’m not even sure I can implement the rules they way I want them. I’ll see if I can get pass this in my backend somehow.

Might I suggest a schema change solution?

Instead of Role being an enum, think about making it a type with each role then being it’s own node. (This may have pros/cons to your situation that you should weigh personally)

Then you could query:

User → UserRole → Role → Company

1 Like

But I would still need to figure out their role, so by making this change I can then just query all roles/types and inside user role/type, just not ask for the data that I dont want to show hmm

type User {
	id: ID! 
	authId: String! @search(by:[exact]) 
	phone: String! @search(by:[exact]) 
	email: String @search(by:[exact]) 
	firstName: String! @search(by:[exact]) 
	lastName: String! @search(by:[exact]) 
	created: DateTime! 
	tags: [Tag] @hasInverse(field:users)
	userRoles: [UserRole] @hasInverse(field:user) 
	…
}

type UserRole  {
	id: ID! 
	user: User! 
	roles: [Role]! @hasInverse(field:userRole) 
	created: DateTime! 
}

type Role  {
	id: ID! 
	userRole: UserRole!
	roleType: RoleType!
    company: Company!
}

type RoleType {
	id: ID!
	name: String! @search(by:[hash])
}

like this?

with some gpt help I don’t think that’ll work, I think I need something like this:

interface RoleBase {
  id: ID!
  userRole: UserRole!
  company: CompanyBase!
}

type AdminRole implements RoleBase {
  id: ID!
  userRole: UserRole!
  company: CompanyWithPhones!
}

type UserRole implements RoleBase {
  id: ID!
  userRole: UserRole!
  company: CompanyBase!
}

interface CompanyBase {
  id: ID!
  name: String!
  phone: String
  email: String
  tags: [Tag]
  created: DateTime!
  start: DateTime!
  end: DateTime
}

type CompanyWithPhones implements CompanyBase {
  id: ID!
  name: String!
  phone: String
  email: String
  tags: [Tag]
  created: DateTime!
  start: DateTime!
  end: DateTime
  allowedPhones: [AllowedPhone]
}

and then

query {
  queryUser {
    id
    authId
    phone
    email
    firstName
    lastName
    created
    tags {
      id
      name
    }
    userRoles {
      id
      roles {
        ... on AdminRole {
          id
          company {
            id
            name
            phone
            email
            tags {
              id
              name
            }
            created
            start
            end
            allowedPhones {
              id
              phone
            }
          }
        }
        ... on UserRole {
          id
          company {
            id
            name
            phone
            email
            tags {
              id
              name
            }
            created
            start
            end
          }
        }
      }
      created
    }
  }
}

does this seem correct, and what you meant ? :slight_smile:

I think I have managed to understand the logic:

Working sample:

interface UserBase { 
        id: ID!
	firstName: String! @search(by:[exact,fulltext]) 
	lastName: String! @search(by:[exact,fulltext]) 
        email: String @search(by:[exact,fulltext])
	tags: [String] @search(by:[exact])
        role: [UserRole] @hasInverse(field:user)
}

interface UserBaseHidden {
  id: ID!
  UserBaseHidden: String
}

interface UserManager {
  id: ID!
  UserManager: String
}

type User implements UserBase & UserBaseHidden & UserManager {
	id: ID!
  authId: String! @search(by:[exact])
  phone: String! @search(by:[exact,fulltext])
  created: DateTime! @search(by:[year])
}

interface CompanyBase {
  id: ID!
  phone: String 
	email: String 
	tags: [String]
  userRoles: [UserRoleUser] @hasInverse(field:company)
}

interface CompanyManager {
  id: ID!
  allowedPhones: [String] @search(by:[exact])
}

type Company implements CompanyBase & CompanyManager {
	id: ID! 
	name: String! @search(by:[exact, fulltext])
	cvr: String! @search(by:[exact])  
	created: DateTime! @search(by:[year]) 
  shutdown: DateTime @search(by:[year]) 
}


type UserRoleUser {
  id: ID! 
  company: CompanyBase!
}

type UserRoleManager {
  id: ID! 
  company: Company!
}

type UserRoleAdmin {
  id: ID! 
  company: Company!
}

union UserRoleType = UserRoleAdmin | UserRoleManager | UserRoleUser

type UserRole {
	id: ID!
  user: UserBase! @hasInverse(field:role)
  userRole: UserRoleType!
  created: DateTime!
}

Query:

query MyQuery {
  queryUser {
    role {
      userRole {
        ... on UserRoleAdmin {
          id
          company {
            allowedPhones
            email
            id
          }
        }
        ... on UserRoleUser {
          id
          company {
            email
            id
          }
        }
      }
    }
  }
}

Response:

"data": {
    "queryUser": [
      {
        "role": [
          {
            "userRole": {
              "id": "0x1a4fdb6d52",
              "company": {
                "allowedPhones": [
                  "1234567890",
                  "0987654321",
                  "1122334455"
                ],
                "email": "info@.com",
                "id": "0x1a4fdb6d4b"
              }
            }
          }
        ]
      },
      {
        "role": [
          {
            "userRole": {
              "id": "0x1a4fdb6d6a",
              "company": {
                "email": "info@.com",
                "id": "0x1a4fdb6d4b"
              }
            }
          }
        ]
      }
    ]
  },

Please let me know if something can be improved :slight_smile: