Introduction to AskQL

AskQL is a new query language that is also a programming language. Read on to see how you can actually get Star Wars with AskQL.

We can query AskQL with askscript. The askscript should be very intuitive for developers, because it looks like a script!

Let’s query the most common first query – hello world!

ask { 'Hello World!' }
Code snippet 1: Hello World script (top) and the result in the playground (bottom).

We can see the server returns “Hello World!”, which is the string we’ve just sent it.

For the next parts, we’re going to use the data set in the playground. You can view the values set on server in this file:

export const customValues: { [key: string]: any } = {
clientNames: ['a', 'b', 'c', 'd', 'e', 'f', 'g'],
hello: 'Hi! This is a AskVM server running on localhost',
revPerClient: {
a: 426,
b: 35,
c: 446,
d: 246,
e: 133,
f: 136,
g: 53,
},
firstName: 'Luke',
middleName: 'LukeLuke',
lastName: 'Skywalker',
fullName: 'Luke Skywalker',
parents: [
{
firstName: 'Padmé',
lastName: 'Amidala',
},
{
firstName: 'Anakin',
lastName: 'Skywalker',
},
],
friends: [
{
id: 0,
firstName: 'Padmé',
lastName: 'Amidala',
},
{
id: 1,
firstName: 'Anakin',
lastName: 'Skywalker',
},
],
};
view raw values.ts hosted with ❤ by GitHub

You can copy-paste the code snippets to the AskQL playground to see them in action and play with.

AskQl – the query language

We said AskQL is a query language, so let’s perform a simple query:

ask {
  query {
    firstName
    lastName
  }
}
Code Snippet 2: A simple query

The query in Code Snippet 2 requests two resources the server exposes for us – firstName and lastName (see the resources file above). A query always returns an object with the wanted properties. You can copy-paste Code Snippet 2 to the playground and run it. The result is shown in Figure 1.

Figure 1: The results of Code Snippet 2

Of course, you could do a more complex query for other resources at the same query:

ask {
  query {
    firstName
    lastName
    parents {
      firstName
      lastName
    }
  }
}
Code Snippet 3

Here we queried the first name and the last name of in the server resources.  We also queried for the parents’ first name and last name.

AskQL – the programming language

As mentioned in the AskQL definition,  AskQL is also a programming language, so let’s do some programming:

ask {  (10 + 5) * 5} // expect 75
Code Snippet 4: A simple mathematical operation

Code Snippet 4 asks our server to do some mathematical calculation. Paste it to the playground and see that it returns 75 as expected.

Of course AskQL has its own syntax. A nice thing about AskQL is that it gives you useful syntax errors. In Figure 2 I purposely got the syntax wrong. We can see AskQL got us covered so we can easily fix our code.

Figure 2: A query with a wrong syntax gives us a very good feedback as to what went wrong – hence we can easily learn the syntax just by trying out scripts.

Fully fledged scripts

We could also use variables and functions for more complex procedures:

ask {
  const factorial: int(int) = fun(n:int):int {
    if (n:lessThan(2)) {
      return n
    }

    n:multiply(factorial(n:minus(1)))
  }

  5:factorial
}
Code Snippet 5: A factorial function with AskQL

This ask code creates a function called factorial that receives an integer and calculates its factorial. You can paste this code into the playground and change the input (let’s say, 6:factorial) to see the magic.

The power is in your hands!

Combining a query language with a programming language is a very powerful tool. 

For instance, we can query and manipulate the data at the same time, assuring the client gets the exact data structure it needs:

ask {
  query {
    fullName: firstName :concat(‘ ‘, lastName) :toUpperCase
  }
}
Code Snippet 6: Querying for a combination of two resources with concat and toUpperCase

In Code Snippet 6 we have a query that returns an object with the fullName property. fullName does not exist in the server resources.

We define fullName by concatenating firstName and lastName – and also using a useful AskQL native resource toUpperCase to return the resulting string uppercased.

You could also look at the more complex example:

ask {
    const maxRevenue = max(revPerClient);
    const minRevenue = min(revPerClient);
    const indexOfMaxRevenue = 0;
    const indexOfMinRevenue = 0;
    for (let i = 0; i < revPerClient:length; i = i + 1) {
        if (revPerClient:at(i) == maxRevenue) {
            indexOfMaxRevenue = i;
        }
        if (revPerClient:at(i) == minEvenue) {
            indexOfMinRevenue = i;
        }
    }
   
    query {
        highestPayingClient: clientNames:at(indexOfMaxRevenue)
        lowestPayingClient: clientNames:at(indexOfMinRevenue)
    }
   
}
Code Snippet 7

Code Snippet 7 is a rather elaborate yet explicit example. It shows some of the power in combining query with programming. 

The client can manipulate the data server side – giving developers on both ends (backend and frontend) full flexibility without the need to do elaborate API meetings in advance.

And there’s much more… for instance – try this command:

ask {
  fetch(‘https://swapi.dev/api/people’):at(‘results’)
}
Code Snippet 8: Asking the server to fetch data from an external resource. This time, the Star Wars API.

Paste Code Snippet 8 into the playground and see what happens.

A Word About Security

Some of you might be thinking right now: “Is this guy crazy? The client can send scripts to be ran on the server?!? That’s EVAL!!!!”

These were my thoughts exactly when I first heard about the project.

Marcin Hagmajer, the author of AskQL, has put my mind to rest:

“Ask’s ask { <askscript> } runs by default on a secure, sandboxed AskVM, which has a separate execution context. We have built in control mechanisms that only allow using external resources you configured. Ask programs are also run with the limits on execution time and stack size restrictions you define.”

Marcin Hagmajer, the author of AskQL

Summary

AskQL is a new query language that allows a user the power of a programming language while querying a server’s resource.

This has the potential of getting rid (almost) completely of long ICD and API documentaitons.  The client side developers just need to know what’s available on the server – and query it the way they want to, without any schema limitations.

In example, think about a frontend developer who needs to query customers and transactions. A non exhustive list of queries might be:

  1. A list of customers
  2. A list of transactions
  3. Which customer did what transaction.
  4. The sum of all transactions
  5. The customer who made the most transactions
  6. The customers sorted by amount spent (taken from the sum of each customer’s transactions)

In REST API, you’d either need multiple queries, multiple end points (for each type of query) or query for the data and manipulate it client side.

In graphQL, for example, you’d might send a schema and get the data – IF (and only IF) the serverside gang made this schema available beforehand.

And this example is very simple – imagine more complex apps with more complex data and needs…

With AskQL, this problem is resolved. You could just write an askscript that asks exactly what you want, send it to the server – and get any type of data you want. All you need to know is – what resources are available on the server.

In addition, the possibility of delegating computation power from the client to a more powerful server is also an advantage – so a server can cache certain heavy computational procedures it received from multiple clients and save time and resources for everyone.

Go ahead and try it yourself. You can clone the https://github.com/YonatanKra/askql-demo repository to quickstart a nodejs server running AskQL right on your own machine.

Thanks a lot to Piotr from xFAANG and Yonatan Doron from Hodash.dev for the kind and thorough review.

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments