Repository: geldata/gel
Pull request: Document setting globals in HTTP/GraphQL
Closes #4314

Problem statement:
Document `globals` argument for HTTP/GraphQL protocols
What is the best way to specify globals in graphql?

In other words, if a resource has a specific access policy, what is the best way to indicate "session data" like the current user ID when interfacing with edgedb over the graphql interface?

Hints from issue discussion:
You can pass a `globals` argument to the endpoint, similar to `variables`.
The keys should be fully qualified, like `"default::global_var"`.

This ought to be documented, of course.
@fritzblue does global even work with your GQL client?

I have added 2 globals `currentUserId` (scalar) and `currentUser` (query).

With the current extension, when I visit `http://localhost:10704/db/edgedb/graphql/explore`
I get the following error:

```
{
  "errors": [
    {
      "message": "TypeError: Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but 'Filterdefault|currentUser@default|currentUser@global' does not.\n\nNames must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but 'default|currentUser@default|currentUser@global' does not.\n\nNames must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but 'default|currentUser@default|currentUser@global' does not.\n\nNames must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but 'Orderdefault|currentUser@default|currentUser@global' does not.\n\nNames must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but 'delete_default|currentUser@default|currentUser@global' does not."
    }
  ]
}
```
@MiroslavPetrik I'm seeing this issue as well (cc @msullivan)
I've also faced with it because it is not documented.

Commit message: Document setting globals

Closes #4314

Patch to review:
diff --git a/docs/clients/graphql/index.rst b/docs/clients/graphql/index.rst
index 846179b3b8e..8e988f1b0f7 100644
--- a/docs/clients/graphql/index.rst
+++ b/docs/clients/graphql/index.rst
@@ -94,6 +94,10 @@ request can contain the following fields:
 - ``variables`` - a JSON object containing a set of variables. **Optional**
   unless the GraphQL query string contains variables, in which case it is
   required.
+- ``globals`` - a JSON object containing global variables. **Optional**. The
+  keys must be the fully qualified names of the globals to set (e.g.,
+  ``default::current_user`` instead of ``current_user`` if the global is in the
+  ``default`` module).
 - ``operationName`` - the name of the operation that must be
   executed. **Optional** unless the GraphQL query contains several named
   operations, in which case it is required.
@@ -118,7 +122,7 @@ submit the following JSON-encoded form with the necessary fields.
   $ curl \
       -H "Content-Type: application/json" \
       -X POST http://localhost:10787/db/edgedb/graphql \
-      -d '{ "query": "query getMovie($title: String!) { Movie(filter: {title:{eq: $title}}) { id title }}", "variables": { "title": "The Batman" }}'
+      -d '{ "query": "query getMovie($title: String!) { Movie(filter: {title:{eq: $title}}) { id title }}", "variables": { "title": "The Batman" }, "globals": {"default::current_user": "04e52807-6835-4eaa-999b-952804ab40a5"}}'
   {"data": {...}}
 
 .. lint-on
@@ -127,8 +131,9 @@ submit the following JSON-encoded form with the necessary fields.
 GET request
 ^^^^^^^^^^^
 
-When using ``GET`` requests, the values for ``query``, ``variables``, etc.
-should be passed as query paramters in the URL.
+When using ``GET`` requests, any values for ``query``, ``variables``,
+``globals``, or ``operationName`` should be passed as query parameters in the
+URL.
 
 .. lint-off
 
@@ -140,6 +145,7 @@ should be passed as query paramters in the URL.
       -G \
       --data-urlencode 'query=query getMovie($title: String!) { Movie(filter: {title:{eq: $title}}) { id title }}' \
       --data-urlencode 'variables={ "title": "The Batman" }'
+      --data-urlencode 'globals={ "default::current_user": "04e52807-6835-4eaa-999b-952804ab40a5" }'
   {"data": {...}}
 
 .. lint-on
diff --git a/docs/clients/http/protocol.rst b/docs/clients/http/protocol.rst
index fbf682061ad..721dd497905 100644
--- a/docs/clients/http/protocol.rst
+++ b/docs/clients/http/protocol.rst
@@ -11,6 +11,8 @@ protocol. Both GET and POST methods use the following fields:
 - ``variables``- contains a JSON object where the keys are the parameter names
   from the query and the values are the arguments to be used in this execution
   of the query.
+- ``globals``- contains a JSON object where the keys are the fully qualified
+  global names and the values are the desired values for those globals.
 
 The protocol supports HTTP Keep-Alive.
 
@@ -29,7 +31,8 @@ submit the following JSON-encoded form with the necessary fields::
 
     {
       "query": "...",
-      "variables": { "varName": "varValue", ... }
+      "variables": { "varName": "varValue", ... },
+      "globals": {"default::global_name": "value"}
     }
 
 


Code review comments:
diff_hunk: @@ -94,6 +94,10 @@ request can contain the following fields:
 - ``variables`` - a JSON object containing a set of variables. **Optional**
   unless the GraphQL query string contains variables, in which case it is
   required.
+- ``globals`` - a JSON object containing global variables. **Optional**. The
+  keys must be the fully qualified names of the globals to set (e.g.,
+  ``default::current_user`` instead of ``current_user`` if the global is in the
path: docs/clients/graphql/index.rst
text: @user1:
I would consider dropping the "instead of ``current_user``" bit; I think it is unlikely to illuminate?

@user1:
Or maybe it will because that's weird in a graphql context?