restQL integrates seamlessly with your current microservice architecture.

There is no need for any implementation server side, just configure the service endpoints, run restQL server and start querying.

Why restQL?

A microservice-based architecture isn’t a silver bullet. Despite its immediate benefits to the service teams, it poses by its very nature a challenge in terms of complexity and performance to the consumers. restQL aims to solve this gap, reducing network round-trips and simplifying microservice orchestration.

There's a nice blog post explaining in more details restQL motivation, the challenges in building such solution and how it compares to Falcor and GraphQL: Tackling microservice query complexity.


restQL GraphQL Falcor
Codeless deploy V X X
No schema duplication V X X
Native browser caching V X X
CDN and Proxy caching V X X
Easy error and failure handling V X X
Available to all languages V V X
Battle tested in large deploys V V V

restQL acts as a bridge between the client and the backend services, so there's no need to duplicate the API schema or to code the backend integrations.

Also, restQL keeps HTTP semantics and by doing so inherit HTTP benefits such as browser native cache, CDN and proxy cache and easy error handling.

What can you do with restQL?

You can find below some restQL features and how they compare to a manual javascript implementation.

Parallel calls

restQL builds a dependency graph and will perform parallel invocations of the listed resources.

restQL

from hero
    with
        name = "Restman"

from villain
    with
        name = "SOAPLord"

javascript

  function loadData() {

    const heroPromise = loadHero({name: "Restman"})
    const villainPromise = loadVillain({name: "SOAPLord"})

    return Promise.all([heroPromise, villainPromise])
      .then(([hero, villain]) => ({
        hero: hero,
        villain: villain
      })

  }

Chained invocations

When you have a service that depends on an information from a previous service restQL will delay the execution of the second service until the first completes.

restQL

from hero
    with
        name = "Restman"

from sidekick
    with
        hero = hero.id

javascript

function loadData() {

  const heroPromise = loadHero({name: "Restman"})

  const sidekickPromise = heroPromise.then(hero => 
                            loadSidekick({heroId: hero.id}))

  return Promise.all([heroPromise, sidekickPromise])
    .then(([hero, sidekick]) => ({
      hero: hero,
      sidekick: sidekick
    })

}

Multiplexed invocations

Sometimes there's a need to retrieve a list from a service and then for each item from that list invoke another service. By default, restQL considers lists as multiplexed invocations and will make a request for each item.

restQL

from search
    with
        role = "hero"

from hero as heroes
    with
        name = search.results.name

javascript

function loadData() {

  const searchPromise = loadSearch({role: "hero"})

  const heroesPromise = searchPromise.then(search => {
    const heroes = search.map(item => loadHero({name: item.name})
    return Promise.all(heroes)
  })

  return Promise.all([searchPromise, heroesPromise])
    .then(([search, heroes]) => ({
      search: search,
      heroes: heroes
    }))

}

Filter

restQL allows to specify which fields should be fetched for each resource. This allows to reduce payload, which is critical to mobile clients.

restQL

  from heroes as hero
      with
          name = "restQL Master"
      only
          skills,
          name,
          archEnemy

Embed

In the JVM world, it's possible to embed restQL directly into your application so you don't have to spin and manage an additional server. This is also an easy approach for parallel requests in Java.

Clojure

(restql/execute-query 
  :mappings endpoints-map 
  :query "from hero with name = $name" :params { :name "Restman" } )/pre>
                

Java

RestQL restQL = new RestQL(config);
restql.executeQuery("from user with name = ?", "Restman");
                

Manage

restQL Manager allows you to easily test new queries, save resources endpoints, check resources status and save queries that can be used by clients just by referencing the query's name.

Fork me on GitHub