Querty: Bringing the Power of SQL to REST APIs in your Web App

Querty: Bringing the Power of SQL to REST APIs in your Web App

\
\
I’ve always worked with REST APIs at the places I’ve worked. And, despite the fact that there’s a lot about REST that I like, I’ve always been a little jealous of devs who get to work with GraphQL. To me, the idea of being able to query my API and get what I want in one query feels right.

\
I like the simplicity of it. When I think about the data I need for any part of my application, thinking about it in terms of a query makes sense. But, this just wasn’t the way the REST world worked. Then, the other day, I ran into Querty.

\
Querty is an npm module that bills itself as a “new (old) paradigm for [REST] data access”. To the point, it’s a small (30 kb) library that allows you to get data from a REST API using SQL-like syntax. When I read that, it got my attention!

\
So, I tried it out. And, I liked it. This article won’t be a tutorial on how to use Querty. The docs are pretty good and go into a lot of detail. Instead, I’ll show you what I think is the best part about it. Then, if you’re interested, you can check it out on npm, and learn more about how to use it. That’ll keep this a nice, short article and let you see if Querty is something you might like, too.

\
Before I go any further, I should let you know that according to the author’s GitHub, Querty is in Beta (at the time of this writing).

\
Ok, now to the good stuff!!

Queries: Just the Data You Want, and More

The main thing I love about Querty is the SELECT query. With it, you can use SQL to get the data you need from your REST API. Here’s a simplified example in pseudo JavaScript:

\

const getMyData = async (id) => {

   const myData = await exec(
      `SELECT users.name,
       posts.title AS postTitle,
       todos.title,
       completed
     FROM users
     LEFT JOIN posts ON users.id = posts.userId
     LEFT JOIN todos ON users.id = todos.userId
     WHERE users.id = ${id}`
    );

}

// Some View
{userData.map((userData) => (
    <div>
      <ul>
       <li>{userData.name}, {userData?.postTitle}, {userData?.title}, {userData?.completed}</li>
      </ul>
    </div>);
}

\
There’s a few things to notice here:

\

  1. Each table in the SQL query corresponds to a REST API endpoint.
  2. Querty supports column aliasing posts.title AS postTitle
  3. I can join data (yay!!!)

\
In contrast, if I was using something like fetch to get the same data, it might look something like this simplified pseudo JavaScript:

\

const getMyData = async (id) => {

   const userRes = await fetch(getUserById(id));
   const user = await userRes.json();
   const postsRes = await fetch(getPostsByUser(users.id));
   const posts = await postsRes.json();
   const todoRes = await fetch(getTodosByUser(users.id));
   const todos = await todoRes.json();

   // Create a dirty merge of the posts and todos
   let primary, secondary;
   if (posts.length > todos.length) {
     primary = posts;
     secondary = todos;
   } else {
     primary = todos;
     secondary = posts;
   }

   const userData = primary.reduce((data, item, idx) => {
      const merged = {...item, ...(secondary[idx] ? secondary[idx] : {}) }
      data.push(merged)
      return data;
   }, [])

}

// Some View
{userData.map((data, idx) => (
  <div>
   <ul>
     <li>{user.name}, {data?.postTitle}, {data?.title}, {data?.completed}</li>
   </ul>
  </div>);
}

\
I know, that’s really messy, but you get the idea!

\
For me, there’s a big difference between these two examples:

\

  • I love how much cleaner, and focused the Querty code looks.
  • I like how much simpler it is that Querty just gives me back the data I want, the way I want it.
  • I don’t have to do a ton of data manipulation.
  • The query itself helps me understand the code better. It’s kind of like having comments about your data right there in the code.

Other SQL Commands

Besides the SELECT query, you can also do INSERT, UPDATE, and DELETE, and Querty supports two ways of using INSERT and UPDATE. You can either use the normal SQL syntax or what’s called Object Syntax. It looks like this (copied from the docs):

\

// Update using SQL-like Syntax
await exec(`UPDATE posts SET title = 'Alfred Schmidt', body = 'Frankfurt' WHERE id = 1`);

// Update using Querty Object syntax
await exec(`UPDATE posts WHERE id = 1`, { title: "Alfred Schmidt", body: "Frankfurt" });

\
This part is OK. I think it’s nice that you can just use one http client for everything. I don’t think I’d use the SQL UPDATE or INSERT syntax much, but the Object syntax isn’t bad.

\

The Rest of Querty

There are a few other nice things about Querty. I’ll mention them briefly here, and if you want to know more, the docs are a good place to go:

\

  1. Querty can work in the Browser or Node.
  2. You can write addons to extend Querty’s functionality.
  3. It supports working with multiple endpoints.
  4. The docs mention Cockatiel Policies. I haven’t worked with those, but they look interesting.
  5. You can cancel requests.
  6. Querty supports fetch options for things like sending headers.
  7. You can configure it to support managing expired auth tokens and auth token refresh.
  8. It supports query parameters and path mapping.

\
If like me, you find Querty interesting, you can read more about it here: Querty.

Leave a Reply

Your email address will not be published.