Apollo-like hooks for REST APIs with React and Ketting
Tags: ketting, rest, react, javascript
Published: 2020-10-03 20:46:09

---
title: "Apollo-like hooks for REST APIs with React and Ketting"
tags:
  - ketting
  - rest
  - react
  - javascript
canonical_url: https://evertpot.com/ketting-6
cover_image: https://evertpot.com/assets/cover/ketting.png
published: true
---

A bit ago we released [Ketting 6][1]. This is the accumulation of about a year of learning on how to better integrate REST APIs with frontend frameworks, in particular React.

It's packed with new features such as local state management, new caching strategies, (client-side) middleware support and change events. It's also the first release that has some larger BC breaks to make this all work.

Releasing Ketting 6 is a big personal milestone for me, and I'm really excited to unleash it to the world and see what people do with. A big thank you to all the people that beta tested this in the last several months!

What's Ketting?
---------------

In short: Ketting is a generic REST client for Javascript. You can use it for pushing JSON objects via HTTP, but the richer your API is in terms of best practices and standard formats, the more it can automatically do for you.

It has support for Hypermedia formats such as HAL, Siren, Collection+JSON, JSON:API and can even understand and follow links from HTML.

It's often said that REST (and Hypermedia APIs) is lacking a good generic client. GraphQL has a lot of advantages, but a major one is tooling. Ketting aims to close that gap.

More information can be found on [Github][1].

React support in Ketting 6
--------------------------

Ketting now has a separate [react-ketting][2] package that provides React bindings to Ketting. These bindings should look very familiar if you've used [Apollo Client][3] in the past.

Lets dive into an example:

Lets assume you have a REST api that has an 'article' endpoint. This returns something like:

```json
{
  "title": "Hello world",
  "body": "..."
}
```

This article is retrieved with `GET`, and updated with `PUT`, this is how you would display it:

```javascript
import { useResource } from 'react-ketting';


export function Article() {

  const { loading, error, data } = useResource('https://api.example/article/5');

  if (loading) {
    return <div>Loading...</div>;
  }

  if (error) {
    return <div class="error">{error.message}</div>;
  }

  return <article>
    <h1>{data.title}</h1>
    <p>{data.body}</p>
  </article>;

}
```

But what about mutations? Unlike GraphQL, mutations in REST APIs often have the same format for `GET` and `PUT`, so sending an updated resource to a server often just means mutating your 'data' and sending it back.

The following example would allow a user to edit an article and send it back:

```javascript
import { useResource } from 'react-ketting';


export function Article() {

  const { loading, error, data, setData, submit } = 
    useResource('https://api.example/article/5');

  if (loading) {
    return <div>Loading...</div>;
  }

  if (error) {
    return <div class="error">{error.message}</div>;
  }

  const changeTitle = (title) => {
    data.title = title;
    setData(data);
  };
  const changeBody = (body) => {
    data.body = body;
    setData(data);
  };

  return <form onsubmit={() => submit}>
    <input type="text" value={data.title} onChange={ev => changeTitle(ev.target.value)  />
    <textarea onChange={ev => changeBody(ev.target.value)}>{data.body}</textarea>
    <button type="submit">Save!</button>
  </form>;

}
```

Whenever `setData` is called, the internal Ketting cache is updated with the new resource state. This is globally stored, based on the uri of the resource.

This means that if multiple components use `useResource` on that same uri, every component will see that update and triggere a re-render.

This is similar to Apollo's local state, except it's still bound to a single resource uri and can eventually be saved.

When `submit()` is called, the `data` is re-serialized and sent in a `PUT` request.

Non-exhaustive list of other changes
------------------------------------

* Multiple cache strategies, such as forever, short and never.
* Support for fetch-middlewares. OAuth2 is reimplemented as such a plugin. These plugins can be added globally, or per-origin.
* `get()` now returns a `State` object, and functions such as `put()` will require one as an argument.
* `put()` now automatically updates the state cache.
* Support for HEAD requests and following links from HEAD response headers.
* PKCE support for OAuth2.
* Links can now be mutated and sent back to the server.
* Nested transcluded items/embeds.
* A separate `post()` and `postFollow()` method.
* Better support for binary responses and `text/*` responses.
* Experimental: Support for Siren actions, HAL forms and submitting HTML forms.

Future plans
------------

The next two things we are working on are:

* Support for more hooks/components for common React/REST API patterns (tell us what you want!).
* Deeper support for forms and actions from HAL Forms, Siren and HTML.
* Websocket support for live server-initiated state pushes.

More links
----------

* The documentation got a complete rewrite and is now hosted on the [Github Wiki][5].
* For a full list of changes and BC breaks, check out the [Upgrading][4] page.

[1]: https://github.com/badgateway/ketting/
[2]: https://github.com/badgateway/react-ketting
[3]: https://www.apollographql.com/docs/react/
[4]: https://github.com/badgateway/ketting/wiki/Upgrading
[5]: https://github.com/badgateway/ketting/wiki