From f13a3495e68ecda68457d58733b8d4084d0ac3a5 Mon Sep 17 00:00:00 2001 From: rderbier Date: Wed, 15 Feb 2023 14:26:47 -0800 Subject: [PATCH] re-organize graphql section --- content/graphql/_index.md | 2 +- content/graphql/api/_index.md | 22 ++- content/graphql/api/api-overview.md | 24 --- content/graphql/authorization/_index.md | 7 - content/graphql/custom/_index.md | 2 +- content/graphql/federation/index.md | 2 +- .../graphql/how-dgraph-graphql-works/index.md | 79 -------- content/graphql/lambda/_index.md | 2 +- content/graphql/mutations/_index.md | 2 +- content/graphql/queries/_index.md | 2 +- content/graphql/quick-start/index.md | 6 +- content/graphql/schema/_index.md | 12 +- .../graphql/schema/authorization/_index.md | 172 ++++++++++++++++++ .../authorization/auth.md} | 0 .../authorization/authorization-overview.md | 0 .../{ => schema}/authorization/mutations.md | 0 .../index.md => schema/directives/_index.md} | 12 +- .../schema/{ => directives}/deprecated.md | 6 +- .../schema/{ => directives}/generate.md | 4 +- .../graphql/schema/{ => directives}/ids.md | 25 +-- .../graphql/schema/{ => directives}/search.md | 2 +- content/graphql/schema/graph-links.md | 37 ++-- content/graphql/schema/migration.md | 2 +- content/graphql/schema/reserved.md | 2 +- content/graphql/schema/schema-overview.md | 16 -- content/graphql/schema/types.md | 23 ++- content/graphql/subscriptions/index.md | 2 +- content/graphql/todo-app-tutorial/_index.md | 2 +- 28 files changed, 262 insertions(+), 205 deletions(-) delete mode 100644 content/graphql/api/api-overview.md delete mode 100644 content/graphql/authorization/_index.md delete mode 100644 content/graphql/how-dgraph-graphql-works/index.md create mode 100644 content/graphql/schema/authorization/_index.md rename content/graphql/{authorization/directive.md => schema/authorization/auth.md} (100%) rename content/graphql/{ => schema}/authorization/authorization-overview.md (100%) rename content/graphql/{ => schema}/authorization/mutations.md (100%) rename content/graphql/{directives/index.md => schema/directives/_index.md} (90%) rename content/graphql/schema/{ => directives}/deprecated.md (91%) rename content/graphql/schema/{ => directives}/generate.md (96%) rename content/graphql/schema/{ => directives}/ids.md (80%) rename content/graphql/schema/{ => directives}/search.md (99%) delete mode 100644 content/graphql/schema/schema-overview.md diff --git a/content/graphql/_index.md b/content/graphql/_index.md index 39855681..4a56c6a8 100644 --- a/content/graphql/_index.md +++ b/content/graphql/_index.md @@ -24,7 +24,7 @@ description = "Generate a GraphQL API and a graph backend from a single GraphQL
- }}"> + }}">

Schema

All the things that you can put in your input GraphQL schema diff --git a/content/graphql/api/_index.md b/content/graphql/api/_index.md index 1ef32458..777f3ddf 100644 --- a/content/graphql/api/_index.md +++ b/content/graphql/api/_index.md @@ -1,7 +1,23 @@ +++ -title = "API" +title = "Client API" [menu.main] identifier = "api" parent = "graphql" - weight = 5 -+++ \ No newline at end of file + weight = 8 ++++ + +How to use the GraphQL API. + +Dgraph serves [spec-compliant +GraphQL](https://graphql.github.io/graphql-spec/June2018/) over HTTP to two endpoints: `/graphql` and `/admin`. + + +In Dgraph Cloud `/graphql` and `/admin` are served from the domain of your backend, which will be something like `https://YOUR-SUBDOMAIN.REGION.aws.cloud.dgraph.io`. If you are running a self-hosted Dgraph instance that will be at the alpha port and url (which defaults to `http://localhost:8080` if you aren't changing any settings). + +In each case, both GET and POST requests are served. + +- `/graphql` is where you'll find the GraphQL API for the types you've added. That is the single GraphQL entry point for your apps to Dgraph. + +- `/admin` is where you'll find an admin API for administering your GraphQL instance. That's where you can update your GraphQL schema, perform health checks of your backend, and more. + +This section covers the API served at `/graphql`. See [Admin](/graphql/admin) to learn more about the admin API. diff --git a/content/graphql/api/api-overview.md b/content/graphql/api/api-overview.md deleted file mode 100644 index f3699260..00000000 --- a/content/graphql/api/api-overview.md +++ /dev/null @@ -1,24 +0,0 @@ -+++ -title = "Overview" -description = "The documentation in this section covers the API served at /graphql. This is where you’ll find the GraphQL API for the types you’ve added." -weight = 1 -[menu.main] - parent = "api" - identifier = "api-overview" -+++ - -How to use the GraphQL API. - -Dgraph serves [spec-compliant -GraphQL](https://graphql.github.io/graphql-spec/June2018/) over HTTP to two endpoints: `/graphql` and `/admin`. - - -In Dgraph Cloud `/graphql` and `/admin` are served from the domain of your backend, which will be something like `https://YOUR-SUBDOMAIN.REGION.aws.cloud.dgraph.io`. If you are running a self-hosted Dgraph instance that will be at the alpha port and url (which defaults to `http://localhost:8080` if you aren't changing any settings). - -In each case, both GET and POST requests are served. - -- `/graphql` is where you'll find the GraphQL API for the types you've added. That is the single GraphQL entry point for your apps to Dgraph. - -- `/admin` is where you'll find an admin API for administering your GraphQL instance. That's where you can update your GraphQL schema, perform health checks of your backend, and more. - -This section covers the API served at `/graphql`. See [Admin](/graphql/admin) to learn more about the admin API. diff --git a/content/graphql/authorization/_index.md b/content/graphql/authorization/_index.md deleted file mode 100644 index d37fd7fc..00000000 --- a/content/graphql/authorization/_index.md +++ /dev/null @@ -1,7 +0,0 @@ -+++ -title = "Authorization" -weight = 4 -[menu.main] - identifier = "authorization" - parent = "graphql" -+++ \ No newline at end of file diff --git a/content/graphql/custom/_index.md b/content/graphql/custom/_index.md index a35aeab2..fae83c2a 100644 --- a/content/graphql/custom/_index.md +++ b/content/graphql/custom/_index.md @@ -1,6 +1,6 @@ +++ title = "Custom Resolvers" -weight = 9 +weight = 6 [menu.main] identifier = "custom" parent = "graphql" diff --git a/content/graphql/federation/index.md b/content/graphql/federation/index.md index eafe8029..e7c633dd 100644 --- a/content/graphql/federation/index.md +++ b/content/graphql/federation/index.md @@ -1,7 +1,7 @@ +++ title = "Apollo Federation" description = "Dgraph now supports Apollo federation so that you can create a gateway GraphQL service that includes the Dgraph GraphQL API and other GraphQL services." -weight = 14 +weight = 12 [menu.main] name = "Apollo Federation" identifier = "federation" diff --git a/content/graphql/how-dgraph-graphql-works/index.md b/content/graphql/how-dgraph-graphql-works/index.md deleted file mode 100644 index bbed9415..00000000 --- a/content/graphql/how-dgraph-graphql-works/index.md +++ /dev/null @@ -1,79 +0,0 @@ -+++ -title = "How GraphQL works in Dgraph" -description = "Dgraph is a GraphQL database. But what does that mean? You design, iterate, and scale your application - all with GraphQL." -weight = 3 -[menu.main] - name = "How GraphQL works in Dgraph" - identifier = "how-dgraph-graphql-works" - parent = "graphql" -+++ - -Dgraph is a GraphQL database. That means, with Dgraph, you design your application in GraphQL, you iterate on your app in GraphQL and, when you need it, you scale with GraphQL. - -You design a set of GraphQL types that describes your requirements. Dgraph takes those types, prepares graph storage for them and generates a GraphQL API with queries and mutations. - -You design a graph, store a graph and query a graph. You think and design in terms of the graph that your app is based around. - -Let's look at how that might work a simple Twitter clone. - -## The app building process - -You'll have an idea for your app, maybe you've sketched out the basic UI, or maybe you've worked out the basic things in your app and their relationships. From that, you can derive a first version of your schema. - -```graphql -type User { - username: String! @id - tweets: [Tweet] -} - -type Tweet { - text: String! -} -``` - -Load that into Dgraph, and you'll have a working GraphQL API. You can start doing example queries and mutations with a tool like GraphQL Playground or Insomnia, you can even jump straight in and start building a UI with, say, Apollo Client. That's how quickly you can get started. - -Soon, you'll need to iterate while you are developing, or need to produce the next version of your idea. Either way, Dgraph makes it easy to iterate on your app. Add extra fields, add search, and Dgraph adjusts. - -```graphql -type User { - username: String! @id - tweets: [Tweet] -} - -type Tweet { - text: String! @search(by: [fulltext]) - datePosted: DateTime -} -``` - -You can even do data migrations in GraphQL, so you never have to think about anything other than GraphQL. - -Eventually, you'll need custom business logic and bespoke code to enhance your GraphQL server. You can write that code however works best for your app and then integrate it directly into your GraphQL schema. - -```graphql -type User { - ... -} - -type Tweet { - ... - myCustomField @custom(...) -} - -type Query { - MyCustomQuery @custom(...) -} -``` - -Again, Dgraph adjusts, and you keep working on your app, not on translating another data format into a graph. - -## GraphQL, Dgraph and Graphs - -You might be familiar with GraphQL types, fields and resolvers. Perhaps you've written an app that adds GraphQL over a REST endpoint or maybe over a relational database. If so, you know how GraphQL sits over those sources and issues many queries to translate the REST/relational data into something that looks like a graph. - -There's a cognitive jump in that process because your app is about a graph, but you've got to design a relational schema and work out how that translates as a graph. You'll be thinking about the app in terms of the graph, but have to mentally translate back and forth between the relational and graph models. There are engineering challenges around the translation as well as the efficiency of the queries. - -There's none of that with Dgraph. - -Dgraph GraphQL is part of Dgraph, which stores a graph - it's a database of nodes and edges. So it's efficient to store, query and traverse as a graph. Your data will get stored just like you design it in the schema, and the queries are a single graph query that does just what the GraphQL query says. diff --git a/content/graphql/lambda/_index.md b/content/graphql/lambda/_index.md index f0a8342c..24c518db 100644 --- a/content/graphql/lambda/_index.md +++ b/content/graphql/lambda/_index.md @@ -1,6 +1,6 @@ +++ title = "Lambda Resolvers" -weight = 9 +weight = 7 [menu.main] identifier = "lambda" parent = "graphql" diff --git a/content/graphql/mutations/_index.md b/content/graphql/mutations/_index.md index 0c457869..004e084b 100644 --- a/content/graphql/mutations/_index.md +++ b/content/graphql/mutations/_index.md @@ -1,6 +1,6 @@ +++ title = "Mutations" -weight = 8 +weight = 4 [menu.main] identifier = "graphql-mutations" parent = "graphql" diff --git a/content/graphql/queries/_index.md b/content/graphql/queries/_index.md index fb4d21c2..f6814075 100644 --- a/content/graphql/queries/_index.md +++ b/content/graphql/queries/_index.md @@ -1,6 +1,6 @@ +++ title = "Queries" -weight = 7 +weight = 3 [menu.main] identifier = "graphql-queries" parent = "graphql" diff --git a/content/graphql/quick-start/index.md b/content/graphql/quick-start/index.md index 6561811a..4c17b9a8 100644 --- a/content/graphql/quick-start/index.md +++ b/content/graphql/quick-start/index.md @@ -8,8 +8,10 @@ weight = 2 parent = "graphql" +++ -Go from an empty Dgraph database to a running GraphQL API in just one step! -Just define the schema of your graph and how you’d like to search it; Dgraph does the rest. +You might be familiar with GraphQL types, fields and resolvers. Perhaps you've written an app that adds GraphQL over a REST endpoint or maybe over a relational database. If so, you know how GraphQL sits over those sources and issues many queries to translate the REST/relational data into something that looks like a graph. + +There's none of that with Dgraph : you can generate a running GraphQL API with the associated graph backend just by dpeloying the GraphQL schema of your API; Dgraph does the rest. + ## Prerequisite : Run Dgraph diff --git a/content/graphql/schema/_index.md b/content/graphql/schema/_index.md index 57e3bb5d..62566edb 100644 --- a/content/graphql/schema/_index.md +++ b/content/graphql/schema/_index.md @@ -3,5 +3,13 @@ title = "Schema" [menu.main] identifier = "schema" parent = "graphql" - weight = 6 -+++ \ No newline at end of file + weight = 2 ++++ + +This section describes all the things you can put in your input GraphQL schema, and what gets generated from that. + +The process for serving GraphQL with Dgraph is to add a set of GraphQL type definitions using the `/admin` endpoint. Dgraph takes those definitions, generates queries and mutations, and serves the generated GraphQL schema. + +The input schema may contain interfaces, types and enums that follow the usual GraphQL syntax and validation rules. + +If you want to make your schema editing experience nicer, you should use an editor that does syntax highlighting for GraphQL. With that, you may also want to include the definitions [here](/graphql/schema/dgraph-schema) as an import. diff --git a/content/graphql/schema/authorization/_index.md b/content/graphql/schema/authorization/_index.md new file mode 100644 index 00000000..b8400d5d --- /dev/null +++ b/content/graphql/schema/authorization/_index.md @@ -0,0 +1,172 @@ ++++ +title = "Authorization" +weight = 5 +[menu.main] + identifier = "authorization" + parent = "schema" ++++ + +Dgraph's GraphQL implementation comes with built-in authorization. This lets you annotate your schema with rules that determine who can query and mutate your data. + +First, let's get some concepts defined. There are two important concepts included in what's often called *auth*: + +* Authorization: access permissions (what are you allowed to do) +* Authentication: establishment of identity (who you are) + +Dgraph lets you use your GraphQL schema to manage both authorization and authentication: +* You set authorization rules by annotating your schema with the `@auth` directive +* You configure authentication methods by providing those settings to Dgraph in the last +line of your schema, in a commented-out `Dgraph.Authorization` object. + +Establishing identity and managing identity-based permissions are closely related, +so this page covers both Dgraph's authorization capabilities, and how Dgraph works with +various authentication methods. + +## Authorization + +You can add authorization rules to your schema using the `@auth` directive. But, +you also need to configure the `Dgraph.Authorization` object (which handles +authentication) on the last line of your schema for the `@auth` directive to +work (as described below). + +When authentication and authorization are complete, your schema should look similar to the following: + +```graphql +type A @auth(...) { + ... +} + +type B @auth(...) { + ... +} + +# Dgraph.Authorization {"VerificationKey":"","Header":"","Namespace":"","Algo":"","Audience":[]} +``` + + +## Authentication + +You can authenticate your users using the following methods: +* A cloud service like OneGraph, Firebase, or Auth0 +* Social sign-in options (such as Google authentication) +* Your own custom authentication code + +Dgraph's GraphQL implementation is completely flexible about how your app does +authentication; instead, Dgraph focuses on authorization. + +Dgraph's GraphQL endpoint supports both symmetric (secret-based) and asymmetric (public key) +encryption. The connection between Dgraph and your authentication mechanism can +be a JSON Web Key (JWK) URL or a signed JSON Web Token (JWT). So, you can provide +Dgraph with the public key of the JWT signer (such as Firebase or Auth0) and +Dgraph trusts JWTs signed by the corresponding private key. + +{{% notice "tip" %}} +To learn more about adding JWTs from a third-party JWT signer to your app, see +[Auth0 Authentication]({{< relref "graphql/todo-app-tutorial/todo-auth0-jwt" >}}) or [Firebase Authentication]({{< relref "graphql/todo-app-tutorial/todo-firebase-jwt" >}}). {{% /notice %}} + +### `Dgraph.Authorization` parameters + +To define the authentication connection method, Dgraph uses a commented-out +`Dgraph.Authorization` object that you should add as the last line of your schema. +You can only use one authentication connection method, either JWT, a single JWK +URL, or multiple JWK URLs. + +The `Dgraph.Authorization` object uses the following syntax: + +```json +{"Header":"", "Namespace":"", "Algo":"", "VerificationKey":"", "JWKURL":"", "Audience":[], "ClosedByDefault": false} +``` + +This object contains the following values: +* `Header` is the header that requests use to store the signed JWT. +* `Namespace` is the key inside the JWT that contains the claims relevant to Dgraph authorization. +* `Algo` is the JWT verification algorithm which can be either `HS256` or `RS256`. +* `VerificationKey` is the string value of the key, with newlines replaced with `\n` and the key string wrapped in `""`: + * **For asymmetric encryption**: `VerificationKey` contains the public key string + * **For symmetric (secret-based) encryption**: `VerificationKey` is the secret key; this can be any secret string you choose, such as one that you generate using a tool like OpenSSL +* `JWKURL`/`JWKURLs` is the URL for the JSON Web Key sets. If you want to pass multiple URLs, use `JWKURLs` as an array of multiple JWK URLs for the JSON Web Key sets. +* `Audience` is used to verify the `aud` field of a JWT, which is used by certain providers to indicate the intended audience for the JWT. When doing authentication with `JWKURL`, this field is mandatory as identity providers share JWKs among multiple tenants. +* `ClosedByDefault`, if set to `true`, requires authorization for all requests even if the type does not specify the [`@auth`]({{< relref "directive.md" >}}) directive. If omitted, the default setting is `false`. + +{{% notice "tip" %}} +To pass multiple URLs, use `JWKURLs` as an array of multiple JWK URLs for the JSON Web Key sets. +{{% /notice %}} + +To set the authentication connection method, do the following: + +* **To use a JWT**: On the last line of your schema, specify a verification key (`VerificationKey`) and encryption algorithm (`Algo`) in the `Dgraph.Authorization` object. Dgraph verifies the JWT against the provided `VerificationKey`. So, your schema should end with a line like the following: + +``` +# Dgraph.Authorization {"VerificationKey":"","Header":"X-My-App-Auth","Namespace":"https://my.app.io/jwt/claims","Algo":"HS256","Audience":["aud1","aud5"]} +``` + +* **To use a single JWK URL**: Specify the `JWKURL` and `Audience` arguments in the `Dgraph.Authorization` object. Dgraph fetches the JWK and verifies the token against it. So, your schema should end with a line like the following: + +``` +# Dgraph.Authorization {"VerificationKey":"","Header":"X-My-App-Auth", "jwkurl":"https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com", "Namespace":"https://xyz.io/jwt/claims","Algo":"","Audience":["fir-project1-259e7", "HhaXkQVRBn5e0K3DmMp2zbjI8i1wcv2e"]} +``` + +* **To use multiple JWK URLs**: Specify the `JWKURLs` and `Audience` arguments in the `Dgraph.Authorization` object. Dgraph fetches all of the JWKs and verifies the token against one of the JWKs, based on the JWK's kind. So, your schema should end with a line like the following: + +``` +# Dgraph.Authorization {"VerificationKey":"","Header":"X-My-App-Auth","jwkurls":["https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com","https://dev-hr2kugfp.us.auth0.com/.well-known/jwks.json"], "Namespace":"https://xyz.io/jwt/claims","Algo":"","Audience":["fir-project1-259e7", "HhaXkQVRBn5e0K3DmMp2zbjI8i1wcv2e"]} +``` + +## Using JWTs and authorization claims + +In addition to the examples shown above, you can configure `Dgraph.Authorization` as follows +to use the `X-My-App-Auth` header and use namespace-based authorization claims: + +- HMAC-SHA256 JWT with symmetric cryptography (the signing key and verification key are the same): + +``` +# Dgraph.Authorization {"VerificationKey":"secretkey","Header":"X-My-App-Auth","Namespace":"https://my.app.io/jwt/claims","Algo":"HS256"} +``` + +- RSA Signature with SHA-256 asymmetric cryptography (the JWT is signed with the private key and Dgraph checks with the public key): + +``` +# Dgraph.Authorization {"VerificationKey":"-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----","Header":"X-My-App-Auth","Namespace":"https://my.app.io/jwt/claims","Algo":"RS256"} +``` + +### Authorization with custom claims + +In both of the examples above, the header `X-My-App-Auth` is required and the +JWT is expected to contain a custom claims object (in this case, `"https://my.app.io/jwt/claims": { ... }`) with the claims used in authorization rules. + +The value of the `X-My-App-Auth` header is expected to be in one of the following forms: +* Just the JWT token. For example: + ```txt + eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJodHRwczovL215LmFwcC5pby9qd3QvY2xhaW1zIjp7fX0.Pjlxpf-3FhH61EtHBRo2g1amQPRi0pNwoLUooGbxIho + ``` + +* A Bearer token, e.g., a JWT prepended with `Bearer ` prefix (including space). For example: + ```txt + Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJodHRwczovL215LmFwcC5pby9qd3QvY2xhaW1zIjp7fX0.Pjlxpf-3FhH61EtHBRo2g1amQPRi0pNwoLUooGbxIho + ``` + +### Authorization with standard claims + +Apart from the custom claims belonging to a given namespace, you can use standard claims in the authorization rules, as shown in the following example: + +```json +{ + "https://xyz.io/jwt/claims": [ + .... + ], + "ROLE": "ADMIN", + "USERROLE": "user1", + "email": "random@example.com", + "email_verified": true, + "sub": "1234567890", + "aud": "63do0q16n6ebjgkumu05kkeian", + "iat": 1611694692, + "exp": 2611730692 +} +``` + +The authorization variables include the rest of the given claims along with the claims provided under namespace `https://xyz.io/jwt/claims`. + +{{% notice "note" %}} +In cases where the same variable is present in both custom claims and standard claims, the variable value in the custom claim takes precedence. +{{% /notice %}} \ No newline at end of file diff --git a/content/graphql/authorization/directive.md b/content/graphql/schema/authorization/auth.md similarity index 100% rename from content/graphql/authorization/directive.md rename to content/graphql/schema/authorization/auth.md diff --git a/content/graphql/authorization/authorization-overview.md b/content/graphql/schema/authorization/authorization-overview.md similarity index 100% rename from content/graphql/authorization/authorization-overview.md rename to content/graphql/schema/authorization/authorization-overview.md diff --git a/content/graphql/authorization/mutations.md b/content/graphql/schema/authorization/mutations.md similarity index 100% rename from content/graphql/authorization/mutations.md rename to content/graphql/schema/authorization/mutations.md diff --git a/content/graphql/directives/index.md b/content/graphql/schema/directives/_index.md similarity index 90% rename from content/graphql/directives/index.md rename to content/graphql/schema/directives/_index.md index 37fa41b2..b98099eb 100644 --- a/content/graphql/directives/index.md +++ b/content/graphql/schema/directives/_index.md @@ -1,11 +1,9 @@ +++ -title = "Index of Directives" -description = "The list of all directives supported by Dgraph. Full details linked within for all directives available with GraphQL." -weight = 11 +title = "Directives" +weight = 4 [menu.main] - name = "Directives" identifier = "directives" - parent = "graphql" + parent = "schema" +++ The list of all directives supported by Dgraph. @@ -32,7 +30,7 @@ Reference: [Custom directive](/graphql/custom/directive) The `@deprecated` directive lets you mark the schema definition of a field or `enum` value as deprecated, and also lets you provide an optional reason for the deprecation. -Reference: [Deprecation]({{< relref "graphql/schema/deprecated.md" >}}) +Reference: [Deprecation]({{< relref "deprecated.md" >}}) ### @dgraph @@ -113,4 +111,4 @@ Reference: [Subscriptions](/graphql/subscriptions) The `@lambdaOnMutate` directive allows you to listen to mutation events(`add`/`update`/`delete`). Depending on the defined events and the occurrence of a mutation event, `@lambdaOnMutate` triggers the appropriate lambda function implemented on a given lambda server. -Reference: [LambdaOnMutate directive](/graphql/lambda/webhook) +Reference: [LambdaOnMutate directive](/graphql/lambda/webhook) \ No newline at end of file diff --git a/content/graphql/schema/deprecated.md b/content/graphql/schema/directives/deprecated.md similarity index 91% rename from content/graphql/schema/deprecated.md rename to content/graphql/schema/directives/deprecated.md index 5e229a87..9b16b4cf 100644 --- a/content/graphql/schema/deprecated.md +++ b/content/graphql/schema/directives/deprecated.md @@ -1,8 +1,8 @@ +++ -title = "Deprecation" -weight = 8 +title = "@deprecated" +weight = 2 [menu.main] - parent = "schema" + parent = "directives" +++ The `@deprecated` directive allows you to tag the schema definition of a field or enum value as deprecated with an optional reason. diff --git a/content/graphql/schema/generate.md b/content/graphql/schema/directives/generate.md similarity index 96% rename from content/graphql/schema/generate.md rename to content/graphql/schema/directives/generate.md index 9d3dfb03..56ef4777 100644 --- a/content/graphql/schema/generate.md +++ b/content/graphql/schema/directives/generate.md @@ -1,9 +1,9 @@ +++ -title = "The @generate Directive" +title = "@generate" description = "The @generate directive specifies which GraphQL APIs are generated for a given type. Without it, all queries & mutations are generated except subscription." weight = 6 [menu.main] - parent = "schema" + parent = "directives" identifier = "schema-generate" +++ diff --git a/content/graphql/schema/ids.md b/content/graphql/schema/directives/ids.md similarity index 80% rename from content/graphql/schema/ids.md rename to content/graphql/schema/directives/ids.md index b24d5668..785622fd 100644 --- a/content/graphql/schema/ids.md +++ b/content/graphql/schema/directives/ids.md @@ -1,9 +1,10 @@ +++ -title = "IDs" +title = "@id" description = "Dgraph database provides two types of identifiers: the ID scalar type and the @id directive." weight = 3 [menu.main] - parent = "schema" + parent = "directives" + identifier = "id-directive" +++ Dgraph provides two types of built-in identifiers: the `ID` scalar type and the `@id` directive. @@ -11,26 +12,6 @@ Dgraph provides two types of built-in identifiers: the `ID` scalar type and the * The `ID` scalar type is used when you don't need to set an identifier outside of Dgraph. * The `@id` directive is used for external identifiers, such as email addresses. -### The `ID` type - -In Dgraph, every node has a unique 64-bit identifier that you can expose in GraphQL using the `ID` type. An `ID` is auto-generated, immutable and never reused. Each type can have at most one `ID` field. - -The `ID` type works great when you need to use an identifier on nodes and don't need to set that identifier externally (for example, posts and comments). - -For example, you might set the following type in a schema: - -```graphql -type Post { - id: ID! - ... -} -``` - -In a single-page app, you could generate the page for `http://.../posts/0x123` when a user clicks to view the post with `ID` 0x123. Your app can then use a `getPost(id: "0x123") { ... }` GraphQL query to fetch the data used to generate the page. - -For input and output, `ID`s are treated as strings. - -You can also update and delete posts by `ID`. ### The `@id` directive diff --git a/content/graphql/schema/search.md b/content/graphql/schema/directives/search.md similarity index 99% rename from content/graphql/schema/search.md rename to content/graphql/schema/directives/search.md index 3ba5d0d3..1fc9407c 100644 --- a/content/graphql/schema/search.md +++ b/content/graphql/schema/directives/search.md @@ -3,7 +3,7 @@ title = "Search and Filtering" description = "What search can you build into your GraphQL API? Dgraph builds search into the fields of each type, so searching is available at deep levels in a query." weight = 5 [menu.main] - parent = "schema" + parent = "directives" identifier = "schema-search" +++ diff --git a/content/graphql/schema/graph-links.md b/content/graphql/schema/graph-links.md index 94141a1a..bdf78239 100644 --- a/content/graphql/schema/graph-links.md +++ b/content/graphql/schema/graph-links.md @@ -1,22 +1,22 @@ +++ -title = "Links in the Graph" -description = "All the data in your app form a GraphQL data graph. That graph has nodes of particular types and links between the nodes to form the data graph." -weight = 4 +title = "Relationships" +description = "All the data in your app form a GraphQL data graph. That graph has nodes of particular types and relationships between the nodes to form the data graph." +weight = 2 [menu.main] parent = "schema" +++ -All the data in your app forms a GraphQL data graph. That graph has nodes of particular types (the types you define in your schema) and links between the nodes to form the data graph. +All the data in your app form a GraphQL data graph. That graph has nodes of particular types and relationships between the nodes to form the data graph. Dgraph uses the types and fields in the schema to work out how to link that graph, what to accept for mutations and what shape responses should take. -Edges in that graph are directed: either pointing in one direction or two. You use the `@hasInverse` directive to tell Dgraph how to handle two-way edges. +Relationships in that graph are directed: either pointing in one direction or two. You use the `@hasInverse` directive to tell Dgraph how to handle two-way relationship. -### One-way Edges +### One-way relationship -If you only ever need to traverse the graph between nodes in a particular direction, then your schema can simply contain the types and the link. +If you only ever need to traverse the graph between nodes in a particular direction, then your schema can simply contain the types and the relationship. -In this schema, posts have an author - each post in the graph is linked to its author - but that edge is one-way. +In this schema, posts have an author - each post in the graph is linked to its author - but that relationship is one-way. ```graphql type Author { @@ -29,29 +29,14 @@ type Post { } ``` -You'll be able to traverse the graph from a Post to its author, but not able to traverse from an author to all their posts. Sometimes that's the right choice, but mostly, you'll want two way edges. +You'll be able to traverse the graph from a Post to its author, but not able to traverse from an author to all their posts. Sometimes that's the right choice, but mostly, you'll want two way relationships. Note: Dgraph won't store the reverse direction, so if you change your schema to include a `@hasInverse`, you'll need to migrate the data to add the reverse edges. -### Two-way edges - edges with an inverse +### Two-way relationship -GraphQL schemas are always under-specified in that if we extended our schema to: -```graphql -type Author { - ... - posts: [Post] -} - -type Post { - ... - author: Author -} -``` - -Then, the schema says that an author has a list of posts and a post has an author. But, that GraphQL schema doesn't say that every post in the list of posts for an author has the same author as their `author`. For example, it's perfectly valid for author `a1` to have a `posts` edge to post `p1`, that has an `author` edge to author `a2`. Here, we'd expect an author to be the author of all their posts, but that's not what GraphQL enforces. In GraphQL, it's left up to the implementation to make two-way connections in cases that make sense. That's just part of how GraphQL works. - -In Dgraph, the directive `@hasInverse` is used to create a two-way edge. +In Dgraph, the directive `@hasInverse` is used to create a two-way relationship. ```graphql type Author { diff --git a/content/graphql/schema/migration.md b/content/graphql/schema/migration.md index 7f3c3d2c..f624e6ef 100644 --- a/content/graphql/schema/migration.md +++ b/content/graphql/schema/migration.md @@ -1,7 +1,7 @@ +++ title = "Schema Migration" description = "This document describes all the things that you need to take care while doing a schema update or migration." -weight = 1 +weight = 5 [menu.main] parent = "schema" identifier = "schema-migration" diff --git a/content/graphql/schema/reserved.md b/content/graphql/schema/reserved.md index a07f4b97..d946d989 100644 --- a/content/graphql/schema/reserved.md +++ b/content/graphql/schema/reserved.md @@ -1,7 +1,7 @@ +++ title = "Reserved Names" description = "This document provides the full list of names that are reserved and can’t be used to define any other identifiers." -weight = 1 +weight = 3 [menu.main] parent = "schema" +++ diff --git a/content/graphql/schema/schema-overview.md b/content/graphql/schema/schema-overview.md deleted file mode 100644 index 611585f3..00000000 --- a/content/graphql/schema/schema-overview.md +++ /dev/null @@ -1,16 +0,0 @@ -+++ -title = "Overview" -description = "These documents describe all the things that you can put in your input GraphQL schema, and what gets generated from that." -weight = 1 -[menu.main] - parent = "schema" - identifier = "schema-overview" -+++ - -This section describes all the things you can put in your input GraphQL schema, and what gets generated from that. - -The process for serving GraphQL with Dgraph is to add a set of GraphQL type definitions using the `/admin` endpoint. Dgraph takes those definitions, generates queries and mutations, and serves the generated GraphQL schema. - -The input schema may contain interfaces, types and enums that follow the usual GraphQL syntax and validation rules. - -If you want to make your schema editing experience nicer, you should use an editor that does syntax highlighting for GraphQL. With that, you may also want to include the definitions [here](/graphql/schema/dgraph-schema) as an import. diff --git a/content/graphql/schema/types.md b/content/graphql/schema/types.md index 71b7aaf4..4395b45d 100644 --- a/content/graphql/schema/types.md +++ b/content/graphql/schema/types.md @@ -1,7 +1,7 @@ +++ title = "Types" description = "How to use GraphQL types to set a GraphQL schema for the Dgraph database. Includes scalars, enums, types, interfaces, union, password, & geolocation types." -weight = 2 +weight = 1 [menu.main] parent = "schema" +++ @@ -51,6 +51,27 @@ type User { Scalar lists in Dgraph act more like sets, so `tags: [String]` would always contain unique tags. Similarly, `recentScores: [Float]` could never contain duplicate scores. +### The `ID` type + +In Dgraph, every node has a unique 64-bit identifier that you can expose in GraphQL using the `ID` type. An `ID` is auto-generated, immutable and never reused. Each type can have at most one `ID` field. + +The `ID` type works great when you need to use an identifier on nodes and don't need to set that identifier externally (for example, posts and comments). + +For example, you might set the following type in a schema: + +```graphql +type Post { + id: ID! + ... +} +``` + +In a single-page app, you could generate the page for `http://.../posts/0x123` when a user clicks to view the post with `ID` 0x123. Your app can then use a `getPost(id: "0x123") { ... }` GraphQL query to fetch the data used to generate the page. + +For input and output, `ID`s are treated as strings. + +You can also update and delete posts by `ID`. + ### Enums You can define enums in your input schema. For example: diff --git a/content/graphql/subscriptions/index.md b/content/graphql/subscriptions/index.md index b9476cb2..e70c5b6f 100644 --- a/content/graphql/subscriptions/index.md +++ b/content/graphql/subscriptions/index.md @@ -1,7 +1,7 @@ +++ title = "GraphQL Subscriptions" description = "Subscriptions allow clients to listen to real-time messages from the server. In GraphQL, it’s straightforward to enable subscriptions on any type." -weight = 8 +weight = 5 [menu.main] name = "Subscriptions" identifier = "subscriptions" diff --git a/content/graphql/todo-app-tutorial/_index.md b/content/graphql/todo-app-tutorial/_index.md index 96761fa6..d8d679ab 100644 --- a/content/graphql/todo-app-tutorial/_index.md +++ b/content/graphql/todo-app-tutorial/_index.md @@ -1,6 +1,6 @@ +++ title = "To-Do List App Tutorial" -weight = 3 +weight = 13 [menu.main] identifier = "todo-app-tutorial" parent = "graphql"