A direct GraphQL "converter" to Dgraph's DQL
language.
Hello everyone,
I am excited to announce that Weasel is undergoing a significant transformation. What began as a library designed for embedded work will now stand as an independent program. My key objectives for this refactoring include:
- The ability to create multiple GraphQL APIs using the same database (Dgraph).
- The possibility to segregate parts of your GraphQL API across various endpoints.
- As the program is standalone, you can have numerous GraphQL APIs within the same context. Or even have pseudo-namespaces.
- Complete mirroring of all Dgraph GraphQL functions.
- Enhancements to several existing Dgraph GraphQL features.
- Addition of more advanced custom queries and mutations.
- Improved Authorization system.
- Introduction of various new features like property validation, both in queries and mutations.
PS. You will be able to run both Weasel and Dgraph's GraphQL in parallel. With full backward compatibility.
Moreover, the program will leverage my expertise to consolidate all these changes.
One of the most significant changes will be the ability to send a schema consisting only of Types (similar to Dgraph), which will automatically generate all query and mutation resolvers(Like CRUD as Dgraph does). The previous Weasel's feature will continue to exist but improved.
The primary reason for this shift is simplicity. This is a terrain I've navigated before, and translating GraphQL to DQL is quite straightforward. With the power of TypeScript and the freedom that comes with being an independent program, we can achieve more and move faster.
My goal is to tackle known issues and simplify others. Granted, the code on the backend will become exponentially more complex. However, being in JavaScript allows for greater control and potentially more contributors to assist in the development, given that the pool of JavaScript developers is larger than that of Golang.
First how it is in Dgraph. | | And How it will be in Weasel.
Weasel is a direct GraphQL "converter" to Dgraph's DQL
language. It is proof of a concept that we can directly relate to both languages.
This project is inspired by join-monster. And it uses the Graphql's AST Object to do it's "magic".
Before you try out (Please, ignore everything below. I will update this later. Everything is gonna change)
This code is extremely embryonic and simple. There is a lot of work to do yet. BTW, help is welcome!
Todo mutations, you need to execute two Dgraph operations. One mutation and then one query. Due to GraphQL's nature of doing a query and returning what was mutated. Dgraph doesn't have this. So you need to do two operations.
To be able to use the reverse directive. You need first pass the @reverse
directive in the reversible edge(s).
Ids will be converted to
uid
.
Using Dgraph Type at query root.
{
getObjects(type: "\"Object\"") {
id
name
friend @reverse {
id
name
}
otherEdge @reverse {
id
name
}
}
}
Using Dgraph's functions at query root.
{
getObjects(func: "eq(dgraph.type, \"Object\")") {
id
name
friend @reverse {
id
name
}
otherEdge @reverse {
id
name
}
}
}
Using Value Facets.
Because GraphQL does not support names with special characters (Such as | pipe, . dot and so on that Dgraph supports). You are required to use aliases with Facets.
{
getAlice(func:"eq(name, \"Alice\")"){
id
name
mobile @facets(aliases: "mobile_since:since")
mobile_since
friend {
name
car @facets(aliases: "car_since:since")
car_since
}
}
}
All these examples you can find in ./examples
To insert data into Dgraph using Weasel, you can choose two ways. Payload or a Typed input.
mutation {
addDataset(input: {
payload: " ... "
})
}
mutation {
addPerson(input: [{
uid: "_:Alice",
name: "Alice",
mobile: "040123456",
car: "MA0123"} (...) ])
}
Upsert Block using type and val (val graphl directive mandatory in case of upsert).
if you send an upsert mutation with root type "User" and the input type "Person". Both will be mutate. E.g.
dgraph_type: ["Person","User"]
mutation {
upsertUser(type: "User",input: {
uid: "uid(v)",
name: "test",
email: "user22@company1.io",
dgraph_type: "Person"
}) @filter(func: "eq(email, \"user22@company1.io\")") {
id @var(val:"v")
name
email
}
}
Upsert Block not using type function at root query.
The field "dgraph_type" will be converted to "dgraph.type".
mutation {
upsertUser(func: "eq(email, \"user_a29@company1.io\")",input: {
uid: "uid(v)",
name: "test",
email: "user_a29@company1.io",
dgraph_type: "Person"
}) {
id @var(val:"v")
name
email
}
}
If you send any upsert mutation without Type anywhere (Root or input), it will assign "dgraph.type":"unknown"
.
mutation {
upsertUser(func: "eq(email, \"44user_88@company1.io\")",input: {
uid: "uid(v)",
name: "test",
email: "44user_88@company1.io"
}) {
id @var(val:"v")
name
email
}
}