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!!
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:
posts.title AS postTitle
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:
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.
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:
fetch
options for things like sending headers.
If like me, you find Querty interesting, you can read more about it here: Querty.