Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/grafoojs/grafoo
A GraphQL Client and Toolkit
https://github.com/grafoojs/grafoo
babel-plugin graphql react typesc typescript
Last synced: 3 months ago
JSON representation
A GraphQL Client and Toolkit
- Host: GitHub
- URL: https://github.com/grafoojs/grafoo
- Owner: grafoojs
- License: mit
- Archived: true
- Created: 2018-03-19T23:24:17.000Z (over 6 years ago)
- Default Branch: main
- Last Pushed: 2023-02-03T04:54:56.000Z (almost 2 years ago)
- Last Synced: 2024-09-25T02:10:32.873Z (3 months ago)
- Topics: babel-plugin, graphql, react, typesc, typescript
- Language: TypeScript
- Homepage:
- Size: 3.42 MB
- Stars: 274
- Watchers: 12
- Forks: 9
- Open Issues: 9
-
Metadata Files:
- Readme: readme.md
- Changelog: changelog.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
- awesome - grafoo - A GraphQL Client and Toolkit (TypeScript)
- awesome-graphql - Grafoo - A tiny yet fully fledged cache based GraphQL client (Libraries / JavaScript Libraries)
- awesome-list - grafoo
- awesome-graphql - Grafoo - A tiny yet fully fledged cache based GraphQL client (Libraries / JavaScript Libraries)
README
A GraphQL Client and Toolkit
Grafoo is a GraphQL client that tries to be different by adopting a **simpler API**, without giving up of a **good caching strategy**.
## Some useful information
- **It's a multiple paradigm library**. So far we have **view layer integrations** for [react](https://github.com/grafoojs/grafoo/tree/master/packages/react) and [preact](https://github.com/grafoojs/grafoo/tree/master/packages/preact) and there are more to come.
- **It's not just a HTTP client**. It comes with a sophisticated caching system under the hood to make sure your data is consistent across your app.
- **It's build time dependent**. A important piece of Grafoo is it's **babel** plugin that compiles your queries based on the schema your app consumes.
- **It's environment agnostic**. Apart from the browser you can run Grafoo on the **server** and even on **native** with react.## Why should I use this
Many of the work that has been put into this project came from borrowed ideas and concepts that are present in the GraphQL clients we have today. Grafoo wants to stand apart from the others trying to be in that sweet spot between **simplicity** and **usability**. Moreover, most of the benefits this library brings to the table are related to the fact that it does a lot at build time. It's **fast**, because it spares runtime computation and it's really **small** (something like **~1.6kb** for core and react) because it does not ship with a GraphQL parser.
## Example applications
You can refer to examples in [this repository](https://github.com/grafoojs/grafoo-examples).
## Basic usage
### Installation
The basic packages you'll have to install in order to use Grafoo are core and babel-plugin.
```
$ npm i @grafoo/core && npm i -D @grafoo/babel-plugin
```### Configure babel
In `@grafoo/babel-plugin` the option `schema` is a path to a GraphQL schema in your file system relative to the root of your project and `idFields` is an array of strings that represent the fields that Grafoo will automatically insert on your queries to build unique identifiers in order to normalize the cache. **Both options are required**.
```json
{
"plugins": [
[
"@grafoo/babel-plugin",
{
"schema": "schema.graphql",
"idFields": ["id"]
}
]
]
}
```### Writing your app
From `@grafoo/core` you will import the factory that creates the client instance and from submodule `@grafoo/core/tag` you'll import the `graphql` or `gql` tag that will be compiled at build time.
```js
import createClient from "@grafoo/core";
import gql from "@grafoo/core/tag";function fetchQuery(query, variables) {
const init = {
method: "POST",
body: JSON.stringify({ query, variables }),
headers: {
"content-type": "application/json"
}
};return fetch("http://some.graphql.api", init).then(res => res.json());
}const client = createClient(fetchQuery);
const USER_QUERY = gql`
query($id: ID!) {
user(id: $id) {
name
}
}
`;const variables = { id: 123 };
client.execute(USER_QUERY, variables).then(data => {
// Write to cache
client.write(USER_QUERY, variables, data);// Do whatever with returned data
console.log(data);// Read from cache at a later stage
console.log(client.read(USER_QUERY, variables));
});// If you wish to reset (clear) the cache:
client.reset();
```### With a framework
Here is how it would go for you to write a simple react app.
#### `index.js`
```jsx
import React from "react";
import ReactDom from "react-dom";
import createClient from "@grafoo/core";
import { Provider } from "@grafoo/react";import Posts from "./Posts";
function fetchQuery(query, variables) {
const init = {
method: "POST",
body: JSON.stringify({ query, variables }),
headers: {
"content-type": "application/json"
}
};return fetch("http://some.graphql.api", init).then(res => res.json());
}const client = createClient(fetchQuery);
ReactDom.render(
,
document.getElementById("mnt")
);
```#### `Posts.js`
```jsx
import React from "react";
import gql from "@grafoo/core/tag";
import { Consumer } from "@grafoo/react";const ALL_POSTS = gql`
query getPosts($orderBy: PostOrderBy) {
allPosts(orderBy: $orderBy) {
title
content
createdAt
updatedAt
}
}
`;export default function Posts() {
return (
{({ client, load, loaded, loading, errors, allPosts }) => (
👆 do whatever you want with the variables above 👆
)}
);
}
```### Mutations
```jsx
import React from "react";
import gql from "@grafoo/core/tag";
import { Consumer } from "@grafoo/react";const ALL_POSTS = gql`
query getPosts($orderBy: PostOrderBy) {
allPosts(orderBy: $orderBy) {
title
content
createdAt
updatedAt
}
}
`;const CREATE_POST = gql`
mutation createPost($content: String, $title: String, $authorId: ID) {
createPost(content: $content, title: $title, authorId: $authorId) {
title
content
createdAt
updatedAt
}
}
`;const mutations = {
createPost: {
query: CREATE_POST,
optimisticUpdate: ({ allPosts }, variables) => ({
allPosts: [{ ...variables, id: "tempID" }, ...allPosts]
}),
update: ({ allPosts }, data) => ({
allPosts: allPosts.map(p => (p.id === "tempID" ? data.createPost : p))
})
}
};const submit = mutate => event => {
event.preventDefault();const { title, content } = event.target.elements;
mutate({ title: title.value, content: content.value });
};export default function PostForm() {
return (
{({ createPost }) => (
submit
)}
);
}
```## LICENSE
[MIT](https://github.com/grafoojs/grafoo/blob/master/LICENSE)