Zodios : an open source HTTP client with type checking at both compile time and runtime (part 1/3)
ecyrbe
Posted on February 20, 2022
You might be familiar zod. It's a schema validation library like many others, that allows you to validate data from user inputs or network request.
The bonus you get from zod compared with the other similar libraries is that it's made from the ground up to use typescript, so it's one of the best to infer your typescript types and not duplicate declarations.
Indeed, with other libraries, you might have to declare your types with typescript and your schema with your validation library.
With zod, you only have to do it once :
const user = z.object({
id: z.number(),
type_of: z.string(),
name: z.string(),
username: z.string(),
});
type User = = z.infer<typeof user>;
/* same as */
type User = {
id: number;
type_of: string;
name: string;
username: string;
};
Zodios
Zodios is a small open-source library that helps you declare your REST APIs in frontend applications thanks to Zod library.
You might be wondering why would you use another library since you might already be using fetch
or axios
to make your api requests.
Indeed, both allow you to make your API calls. But maybe some of you are experiencing the same issues all the time. You might need to :
- Validate your API results and have to write both your types and schemas,
- Have autocompletion and end-up using client api code generators like swagger editor client generator.
Zodios was made to address both these uses cases without having to rely on third party code generators that might produce unmaintainable code.
A basic example :
Before diving into more complex example in the second part of this article, here is a simple one.
We want to call the excellent jsonplaholder service to get all it's users and be able to filter the result with raw text search.
The endpoint we want to call : https://jsonplaceholder.typicode.com/users?q=ell
And here is how you would declare everything with zodios :
const apiClient = new Zodios(
"https://jsonplaceholder.typicode.com",
// API definition
[
{
method: "get",
path: "/users",
description: "Get all users",
parameters: [
{
name: "q",
description: "full text search in users",
type: "Query",
schema: z.string(),
},
],
response: z.object({
id: z.number(),
name: z.string(),
email: z.string(),
address: z.object({
street: z.string(),
suite: z.string(),
city: z.string(),
zipcode: z.string(),
geo: z.object({
lat: z.string(),
lng: z.string()
}),
}),
},
] as const,
);
const users = await apiClient.get("/users", { queries: { q: "ell" } });
console.log(users);
We see that we created a new instance of Zodios
and we provided to it:
- the base URL of jsonplaceholder
- a user API declaration with something looking a lot like a schema or model declaration, but instead of using
openapi
json schema, we usedzod
syntax.
We then called this instance like we almost would with axios
.
But what Zodios gives you with this schema declaration, is autocompletion and types with typescript out of the box.
Indeed, if you hover your mouse over the users
variable in your typescript IDE, you'll get this :
const users: {
id: string;
name: string;
email: string;
address: {
street: string;
suite: string;
city: string;
zipcode: string;
geo: {
lat: string;
lng: string;
};
};
}[]
Your IDE just infered the types based on Zodios API declaration.
You'll also get autocompletions for all the parameters of the API telling you to provide in queries
the q : string
property.
Behind the scene, zodios is using Zod
type inference and some custom typescript utility types.
Conclusion
Like many tools, this solution might not please everyone needs. Some might still prefer code generation tools to handle client API generation.
Zodios has the advantage of letting you in control with minimum boilerplate.
In the next articles, we will see :
- How to declare alias endpoints
- How to declare CRUD endpoints easily
- How to handle large APIs declarations (like the one of dev.to).
- How to split zod declarations and API declarations into multiple files.
You can see the example we'll talk about here
Posted on February 20, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
February 20, 2022