GraphQL endpoint with generated API, introspection, and mutation behavior

Hi @forstmeier

You can use an interface but since its just being implemented by a single type so you can have it as type also. Also you don’t need to specify the hasInverse directive twice for same field. The schema can be modified to something like this -

type User {
  id: ID!
  email: String! @id @search(by: [hash])
  password: String!
  firstName: String!
  lastName: String!
  orgs: [Membership!]! @hasInverse(field: user)
}
type Org {
  id: ID!
  name: String!
  users: [Membership!]! @hasInverse(field: org)
  items: [Item!]! @hasInverse(field: org)
}
type Membership {
  id: ID!
  user: User!
  org: Org!
  role: Role!
}
enum Role {
  ADMIN_USER
  INTERNAL_USER
  EXTERNAL_USER
}
type Item {
  id: ID!
  org: Org!
  parent: Item @hasInverse(field: children)
  children: [Item!] @hasInverse(field: parent)
  description: String @search(by: [fulltext])
}
  1. Yes that sounds like a decent approach, have two files. Then while forming the user-facing API you would have to merge the two. Soon custom-logic feature will be released that will allow you to call a remote endpoint(http/graphql), which you can specific in the GraphQL schema file of Dgraph.

  2. You can use tools like GraphQL playground, Insomnia to introspect the schema. The support currently in Postman for GraphQL isn’t that good.

  3. Yeah you can use email if you know that it will be unique. Yes the relationship between the entities is removed along with its references. The best way to form the types depends on your specific use case and how you will query/mutate the data in your application.

Let me know if you have any more questions.

1 Like

@vardhanapoorv Super helpful, thanks! Just a few quick follow ups:

  • I’ll circle back to dig into the introspection stuff in a bit because right now I’m drastically redesigning the schema - is there any sort of just “placeholder” field I could request on the Delete* mutations? Just for testing/validation purposes. I can also spin up the UIs you mentioned and point them at Dgraph with my updated schema (once it’s ready).
  • What is the behavior of Dgraph when one of these objects is deleted? For example, if the User object is deleted, what happens to the references to it that exist on other objects in the database?

Thanks again! This is really, really helpful.

Hi @forstmeier

Yes you can get the msg field which would have the value something as Deleted on success.
When an object is deleted, all its references on other objects are removed as well.

Let me know, if you have any more questions.

1 Like

Another quick question: any suggestions on handling multi-tenancy? I saw this discussion from a while ago and what I was thinking is on the front-end API (generated through gqlgen) I’ll have various directives for filtering query access by user permissions (so different objects can only be fetched by users with specific permission levels) but I’m curious as to the best route to prevent users from accessing each other’s Orgs or across Projects in the contrived example below.

type Org {
  Name: String!
  Projects: [Project!]!
}

type Project {
  Name: String!
  Items: [Item!]!
}

type Item {
  Name: String!
}

Where I could have multiple Orgs in the system and not want users belonging to one to be able to access Projects/Items in another Org. And also not have users who are invited to specific Projects within an org to not be able to see other Projects within the same org. Maybe this is a case for using directives again but I’m not sure if I want to attach Org/Projects to every other object within the schema? Just thinking out loud.

Hi @forstmeier
We have been working on providing this through Auth directive. This should be merged in master in the upcoming weeks. This will allow you to implement permissions easily that you can just define in the GraphQL schema.

Let me know if you have any more questions.

@vardhanapoorv Is there an open issue/pull request to track progress on that directive? I didn’t see one when I checked but I may have missed it. I’d also be interested in a list of whatever custom schema-side directives Dgraph provides (in addition say to the GraphQL-spec @skip/@include) if that’s available somewhere; I would also assume that this new potential @auth provided by Dgraph would be in that list.

Hi @forstmeier

Soon a post will be published around the progress of Auth directive. Yes all the custom schema-side directives will be included in the docs soon along with GraphQL-spec directives like @skip/@include.

Let me know if you have any more questions.

Sort of unrelated to the above questions but throwing it here since you’ve been super helpful:

  • delete: I’ve been able to use set correctly (updating scalar fields and list fields) but I’m running into issues with this query with the GraphQL endpoint
{
	"query": "mutation updateCustomer($input: UpdateCustomerInput!) { updateCustomer(input: $input) { customer { username reviews { comment } } } }",
	"variables": {
		"input": {
			"filter": {
				"username": {
					"eq": "Michael"
				}
			},
			"delete": {
				"reviews": ["0x8"]
			}
		}
	}
}

where the delete is receiving an unknown field response. Basically, I want to remove either a specific field or an element in a list for a field.

  • schema introspection: I’ve been running into a wall trying with running introspection against the GraphQL endpoint while running locally. I’m trying things like the root GraphQL documentation as well as queries like the one below
{
	"query": "query getGQLSchema { generatedSchema }"
}

but now luck. Where am I going wrong? Being able to see the queries (inputs and outputs) and types (like filters) that have been generated would really speed up my iterations on the schema.

P.S. There appears to be a tiny typo in the GraphQL docs:

PostFilter will contain less than le , less than or equal to le , equal eq , greater than or equal to ge and greater than gt search on numLikes .

^ I think the “less than” should be lt.

Hi @forstmeier

If you want to remove a value from list you should use remove and use the delete mutation if you want to delete like the complete customer in this case. I think when you check the generated mutations and queries definitions that will make it easy for you. So I’m attaching the screenshots from Insomnia (you could be using a different tool) to try/view queries or mutations.

Screenshot 2020-05-03 at 11.56.54 PM Screenshot 2020-05-03 at 11.57.01 PM Screenshot 2020-05-04 at 12.03.35 AM

I hope these will help you to view queries/mutations available to you.

Thanks for the typo mention. Btw here are the two posts I told you that were coming out soon.


Let me know if you have anymore questions.

1 Like

@vardhanapoorv Again, absolute legendary support.

  • I’ve updated my mutations to include remove instead of delete so problem solved there.
  • I was using some other tools but Insomnia is much better at revealing the schema which is immensely helpful.
    • One quick follow up here: is it possible to fetch the entire generated schema out of Dgraph? I’d like to feed parts or all of the file into gqlgen and create an API using that.
  • Both of those posts are super valuable. I’ve started implementing my own solution for authorization (the example for authentication is very helpful and I’ve been adjusting it to suite my needs) - I’ll still definitely keep an eye out for @auth because I feel like that is a much cleaner solution.
  • I’d like to get actively involved in contributing to Dgraph - would you recommend any specific repo to start with? I’m particularly interested in contributing to the test suites or to documentation - whatever would be the most help for me to work on.

Best,
John

2 Likes

The endpoint at /admin lets you query the SDL of the input and generated schemas

Input schema:

query {
  GQLSchema { schema }
}

Generated schema:

query {
  GQLSchema { generatedSchema }
}
1 Like

Hi @forstmeier

Here are few main repos https://github.com/dgraph-io/dgraph and https://github.com/dgraph-io/badger that you can contribute to. Soon the GraphQL docs site will be updated and then you can contribute to that as well.
Let me know if you have anymore questions.

1 Like

Hi, @michaelcompton I saw what looks like either complete, or nearly complete, work on the @auth directive get merged in today - wow, you guys move fast! I’m definitely most interested in this particular directive because I’m faced with a dilema.

  • I want to use Dgraph as my backend and expose a GraphQL frontend
  • I’d like to use gqlgen to save a lot of manual implementation work
  • Ideally, I’d just use Dgraph’s generated schema (as you helped me fetch in an earlier reply) but I’d still need to add in stuff like my own directives (e.g. @isAuthenticated and @isAuthorized) to specific queries/mutations to provide fine-grained control but finding a good tool to parse the output programmatically into Go code for me to manipulate is taking time

Alternatively, having something like a light authentication/etc middleware in a simple net/http server that is basically “passthrough” to the Dgraph API sounds pretty good so long as the @auth can be applied to use a fine-grained control/multi-tenancy resource. Does that make sense?

Hi, yeah @auth got merged. There will be docs and sample apps coming up over the next couple of weeks.

There’s two general approaches you can now take with Dgraph GraphQL

  1. have Dgraph as the exposed server - for that you’d use a combination of custom resolvers and auth (with @custom and @auth)
  2. implement some of the backend with Dgraph (maybe still using @auth and @custom) and then layer something else in front (gqlgen server in your case)

…actually there’s also a 3, which would be some sort of GraphQL Federation.

In all those scenarios, you would be free to use @auth as a fine grained auth - basically what you can say in that is these are the conditions under which you can see/edit this node; those conditions can be a combination of passed in values from a JWT, graph search or a combination of both.

Since there’s docs and samples landing in the next little while, I think the best way forward is for us to share those as soon as possible, or for us to jump on a quick call and have a chat.

Awesome! I’d probably go down the route of doing something more along the lines of #1 you mentioned above at least as an initial cut for the backend service which would basically just be a very light wrap on top of Dgraph. You guys moved fast on getting @auth done!

And yes, docs/examples would be awesome and I could always do a call depending on your availability. I’d also be happy to help write up documentation if needed.

1 Like

I’ve pivoted to definitely follow this @auth directive route given you have already implemented the changes and all that’s left is the documentation. Is there an ETA on those just for my planning purposes?

I’ll be doing the first cut over the next week.

Docs site should also change in that time so you can select between Dgraph v20.03.1 and what’s in master/beta. So we’ll try to get the in progress docs live as soon as we can.

1 Like

Awesome, I think how to use the new @auth directive in conjunction with something like JWTs issued by Auth0 would be super value-added.

Yes we have tried it with JWTs issued by Auth0 and would also add that as an example in the docs.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.