Custom Block - Discussion

PS. Some people may think that GraphQL Vars would be the same as a custom block at some level. But it is not possible to re-sign a G. Vars. Something that would be necessary to be reused in other blocks. One of the intentions would be to “append” values from other blocks and use them in third blocks. That’s not possible in G. Vars.

I would like to open a discussion on introducing a “Custom Block”.
Today only aggregation can use Empty Blocks e.g:

“Only aggregated variables allowed within empty block.”

The utility of a custom block would be enormous:

Of course a simplification of these ideas would be gladly already.

  • Summarize values of different queries
  • Maybe expand a whole nested block values from a assigned var in one place (as a list) just expand, not do any other function/filter in the custom block. e.g:

Basic example of the block:

{
  var() { 
#This is a "custom var block" all values here doesn't show up in the query result.
   ST as string("Alice") #We could use it in_ any query help to avoid repetition.
   T1 as string($a) # This is getting a value from graphql variable.
   T2 as string($a, $a, val(x)) # This is getting values from variables and concatenating.
   Users  as  uidAt(Var1, var2) #converts UID to hex number to be used in a query, also to work with uid_in function.
   Users2 as uidAt("0x1, 0x2") #Just holds UIDs to be used in the query.
   DP as math(4) #hold a number or do a math, as we do in_ our examples in_ docs
   T2 as math($b + 33) # This is getting a value from graphql variable and summing.
   DP2 as int(1) #just hold a number
   DP3 as float(1.01111) #just hold a float number
   DT as dateTime(2006-01-02T15:04:05) #just hold dateTime
     }
  }

example, Instead of:

{
  	me(func: uid(10005, 10006, 10001, 10002, 10003, 10004, 10007, 10000), orderasc: name, orderasc: age, first: 4, offset: 3) {
	  	name
	  	age
	  }
  }

With custom block we could do:

{
  custom() { # to hide this block we use the keyword "var" instead of "custom".
   Users as uid("10005, 10006, 10001, 10002, 10003, 10004, 10007, 10000")
   DP as  math(4) #Defined Pagging
 }

   me(func: uid(Users), orderasc: name, orderasc: age, first: val(DP), offset: 3) {
	  	name
	  	age
	  }
  }

Result

{
	"data": {
		"custom": [{
				"Users": "10005, 10006, 10001, 10002, 10003, 10004, 10007, 10000",
				"DP": "4"
			}
		],
		"me": [{
				"name": "Lucas",
				"age": "21"
			},
              (...)
		]
	}
}

Other ideas:

{
  var(func: uid (0x22f)) {
    myVar as pred_1 @filter(...)
  }
  var(func: has(test)) {
    myVar2 as pred_2 @filter(...)
  }
  me() {
    myAlias : expand(val(myVar)) 
    myAlias2 : expand(val(myVar2))  
    #""message": "expand() cannot have an alias"
  }
}
{
"me": [
  { 
  "myAlias ": [
      {
        "name@.": "Test one"
      },
      {
        "name@.": "Test two"
      }
    ]
},
{ 
  "myAlias2 ": [
      {
        "name@.": "This has test"
      },
      {
        "name@.": "This has test 2"
      }
    ]
}
]
}
  • The user could use the block to create “Stats” according to variables results.
  • The user could explore mathematical functions on this block.
  • The values of this custom block could be used in other blocks. As it would be a summarize of possible important values. This could be useful for propagate rules to root/filters in other blocks.
  • The user could use this like a “header” by placing custom values ​​as variables to be used in the subsequent queries.
    In this case above “headers” would be useful with this Support include directive · Issue #850 · dgraph-io/dgraph · GitHub e.g:
curl localhost:8080/query -XPOST -H 'X-Dgraph-Vars: {"$admin": true}' -d '
   query test($admin: boolean) {
        header_admin() @include(if: $admin) {
          custom_rules ...
          paging _limit as math(10000)
        }
        header_user() @include(if: $admin = false) {
          custom_rules ...
          paging _limit as math(500)
      }
        myQuery1(func: some, first: val(paging _limit) ) {
             #Using the custom blocks rules
      }
        myQuery2(func: some, first: val(paging _limit)) {
             #Using the custom blocks rules
      }
}

What you think?

Cheers.

1 Like

We’re trying to align our queries to GraphQL spec. As such, the main focus is towards ensuring compatibility, instead of introducing new features within GraphQL±. Once we achieve compatibility with GraphQL tools, we can consider building more features in the QL.

The expand function, instead of us storing the list of predicates corresponding to each node, I want to switch it so that users tell us the node type and what edges correspond to a type. So, we use that information.

2 Likes