Why "KY" is Like fetch(), But Better (and When to Consider It)

Why "KY" is Like fetch(), But Better (and When to Consider It)

In the world of JavaScript, the landscape of making HTTP requests has evolved significantly. Not long ago, axios was the go-to library for handling server communication, providing a reliable and consistent way to fetch data on the client. However, with the advent of fetch, which has become the standard for modern web development, many developers have shifted to using it as their primary tool. While fetch is undoubtedly a powerful and flexible tool, it isn't without its quirks and limitations.

This brings us to "KY," a small and elegant HTTP client that offers a more convenient API for making HTTP requests. In this blog post, we'll explore why KY might be a better alternative to fetch() for certain use cases, and when it makes sense to adopt it in your project.


A Brief History of HTTP Requests in JavaScript

Before fetch became widely available, developers relied heavily on axios for making HTTP requests. Axios was popular because it handled many common tasks, like setting default headers or dealing with JSON responses, in a way that was more straightforward than the older XMLHttpRequest. However, once fetch was introduced, it quickly became the standard due to its simplicity and the fact that it was built into the browser.

That said, while fetch is great, it's not perfect. For instance:

- It doesn't treat non-200 status codes as errors by default.

- It lacks built-in timeout support.

- Retrying failed requests is something you have to implement yourself.

- Working with JSON in fetch can be tricky and often leads to mistakes, especially for those new to the API.

These shortcomings create an opportunity for a library like KY to come in and smooth out some of these rough edges.


What is KY?

KY is a small HTTP client built on top of the fetch API. It offers a simplified API that addresses many of the pain points associated with fetch, including:

- Error Handling: Non-200 responses are treated as errors, so you can use try/catch blocks more effectively.

- Timeout Support: KY includes built-in support for request timeouts.

- Retry Mechanism: KY can automatically retry failed requests, with a default of two retries.

- Improved TypeScript Support: When working with JSON, KY’s TypeScript support ensures that you get better type safety.

Here’s a quick comparison:


With fetch:

async function getTodos() {
    const response = await fetch('/todos');
    if (!response.ok) throw new Error('Failed to fetch');

    return response.json();

}

async function addTodo(todo) {
    const response = await fetch('/todos', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(todo)
    });

    if (!response.ok) throw new Error('Failed to add todo');

    return response.json();
}        


With KY:

import ky from 'ky';

async function getTodos() {
    return await ky.get('/todos').json();
}

async function addTodo(todo) {
    return await ky.post('/todos', { json: todo }).json();
}        

Customizing request

To add the access token for each request, you can use the following code with ky:

const api = ky.create({
  prefixUrl: "https://example.com/api",
  headers: {
    Accept: "application/json",
    "Content-Type": "application/json",
  },
  // use a hook to add the authorization header before each request
  hooks: {
    beforeRequest: [
      (request) => {
        request.headers.set("Authorization", "Bearer token")
      },
    ],
  },
})

const response = await api.get("users")
const data = await response.json()
console.log(data)        

Notice that:

  • Ky uses the hooks.beforeRequest option to add a hook function that modifies the request headers, while axios uses the interceptors.request option to add an interceptor function that modifies the request config.
  • Ky uses the request.headers.set() method to set the header value, while axios uses the config.headers object to set the header value.
  • Ky and axios have the same syntax for creating an instance, except for the hooks and interceptors options.
  • Ky supports multiple functions in the hooks.beforeRequest option, which will be executed in order before the request is sent. This allows you to perform different modifications or actions based on the request. For example, you can add a function to log the request details, and another function to add a custom header. You can also use async functions in the hooks, which will wait for the promise to resolve before proceeding to the next hook or the request. Axios also supports multiple functions in the interceptors.request option, but they are executed in reverse order, which can be confusing.
  • As you can see, KY simplifies the syntax and reduces the chances of common mistakes, like forgetting to set the Content-Type header.


The Trade-Offs

While KY offers some clear benefits, it’s important to weigh the trade-offs before deciding to include it in your project. The primary advantage of fetch is its ubiquity; every web developer is familiar with it, and it's a part of the standard API, meaning there's zero cognitive overhead when a new developer joins your team.

KY, while small (just 3.3 KB minified and Gzipped), introduces an additional dependency. In a large project with many developers, even small dependencies can add up in terms of maintenance and cognitive load.

Moreover, KY's improvements over fetch might not be significant enough to justify its inclusion in every project. For example, if you're already using a library like React Query, which abstracts away a lot of the boilerplate associated with fetch, the benefits of KY might be negligible.


KY vs. React Query

It’s worth noting that KY is not a replacement for something like React Query. React Query simplifies data fetching in React by handling caching, synchronization, and more. The difference between vanilla React with fetch and using React Query is massive, making React Query almost indispensable for React developers dealing with asynchronous data.

On the other hand, the difference between fetch and KY is more subtle. It might save you a few lines of code and make certain things a bit easier, but it's not going to revolutionize the way you write your data-fetching logic.


When Should You Use KY?

Consider using KY if:

- You frequently find yourself writing repetitive boilerplate code with fetch.

- You need features like automatic retries or better error handling but don't want to implement them from scratch.

- You're working on a smaller project where introducing a new dependency isn't a big concern.

- You want slightly better ergonomics when working with JSON and TypeScript.

However, if you're already using a more comprehensive solution like React Query or if you're working in a large team where consistency is key, sticking with fetch might be the better choice.


KY is a neat little tool that smooths over some of the rough edges of fetch. While it won't completely replace fetch in every project, it offers enough convenience to be worth considering, especially in smaller projects or for developers who want to avoid some of the common pitfalls associated with fetch. Just remember, every abstraction comes with its trade-offs, and it’s essential to weigh the benefits against the potential downsides before making a decision.

Until next time, fetch wisely!

要查看或添加评论,请登录

Bibin Thomas的更多文章

社区洞察

其他会员也浏览了