wp-headless / fetch

Isomorphic Wordpress API client and React hooks - super tiny, super fast.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

wp-headless

drone Coverage Status npm Bundle size

(Currently in alpha release - use in production at your own risk)

Fetch

A Wordpress API client that works both in the browser and in Node. Tiny footprint, > 95% code coverage, browser tested down to IE11, tree shakable CJS and ES6 builds, expressive syntax.

Why?

There are great alternatives such as wpapi and yllet although both of these projects have issues:

  • Long unresolved browser issues
  • Bloated packages size
  • No tree-shakable ESM or CJS build available
  • Opinionated API that attempts to do more then is needed.
  • Lack of automated browser testing and coverage

We intend to build and support a lean and well tested packages that fit into the modern ES6 javascript ecosystem.

Client

The fundamental tool in the wp-headless ecosystem is the API client.

Installation

Yarn

yarn add @wp-headless/client

NPM

npm install @wp-headless/client

Usage

Creating a client instance bound to the endpoint of your Wordpress install:

import Client from '@wp-headless/client';

const client = new Client('https://demo.wp-api.org/wp-json');

Fetching posts:

// post with id 123
const post = await client.posts().get(123);
// post with slug 'hello-world'
const post = await client.posts().slug('hello-world');
// All posts
const posts = await client.posts().get();
// filtered posts
const posts = await client.posts().get({
  per_page: 10,
  orderby: 'title',
  search: 'Dog fetches bone'
});

Fetching pages is the same as above, simply change the resource endpoint as follows:

// page with id 456
const page = await client.pages().get(456);

Resources

The client provides the following API resource methods:

  • client.categories()
  • client.comments()
  • client.media()
  • client.statuses()
  • client.posts()
  • client.pages()
  • client.settings()
  • client.tags()
  • client.taxonomies()
  • client.types()
  • client.users()

These resource methods are simply syntax sugar for setting the path and namespace to an API resource. Therefore the following are equivalent:

const posts = await client.posts().get(123);
const post = await client.get('posts/123');

Adding custom resource methods is easy (example WooCommerce REST API), the following would fetch the enpoint http://demo.wp-api.org/wp-json/wc/v2/products:

client.products = () => client.namespace('wc/v2').resource('products');

const products = await client.products().get();

Of course you could simply also do the following:

const product = await client.namespace('wc/v2').get('products/123');

As you can see building requests is as simple as setting the namespace(), resource() and the HTTP method; get(), post(), put(), patch() or delete().

HTTP methods

Client instances also provide access to HTTP methods to access API resources.

client.get(); // Http GET
client.create(); // Http POST
client.update(); // Http PATCH
client.delete(); // Http DELETE

For example:

// create a post
const post = client.posts().create({
  title: 'Dog fetches ball',
  content: '<p>then he brings it back</p>'
});
// update the post
const post = client.posts().update(post.id, {
  excerpt: 'Its just what dogs do...'
});
// delete the post
client.posts().delete(post.id);

Request parameters

You can pass request parameters as an object to any of the above methods:

// REQUEST URI https://demo.wp-api.org/wp-json/wp/v2/posts
// REQUEST BODY { title: 'Hello doggy', content: 'fetch a bone' }
const post = client.posts().create({
  title: 'Hello doggy',
  content: 'fetch a bone'
});

Or with a get request

// REQUEST URI https://demo.wp-api.org/wp-json/wp/v2/posts?per_page=10&status=draft
const post = client.posts().get({
  per_page: 10,
  status: 'draft'
});

Its also possible to set global params that will be sent with each request:

// Sets a single param key/value
client.param('per_page', 20);

// Merges an object with current global param values
client.param({
  per_page: 20,
  orderby: 'title'
});

To retrieve global params:

// Single value
client.param('source'); // wp-headless

// All values
client.params;

Embed data

WordPress API supports embedding of resources and instead of having to provide ?_embed=true as a param on every request you can simpley use embed() before any request methods.

More about WordPress API embedding can you read here.

const posts = await client
  .posts()
  .embed()
  .get();

Or globally for all requests:

client.param('_embed', true);

const posts = await client.posts().get(); // now embeded

Syntactical sugar (helper functions)

Sometimes its helpful to have expressive methods that wrap the underlying api, making code more readable and clean.

slug(string: slug)

Slug method is a shortcut to fetch a single post, custom post or page via its post_name (slug) attribute.

const post = client.page().slug('sample-page');
// ...equivalent to
const post = client
  .page()
  .get({ slug: 'sample-page', per_page: 1 })
  .then(posts => posts[0]);

more

We endevour to add a minimal set of sugar to this library, keeping it small, lean and bloat free is imperative.

Transport layers

The architecture of Fetch allows you to specify your own transport layer such as fetch or axios. This allows devs to use a library that they are familiar with, and perhaps are already using in their app, saving bundle size.

Fetch

The client uses the Fetch API Standard to make requests. This is supported in all modern browsers and newer versions of Node.

To support older browsers you will have to implement a polyfill such as isomorphic-fetch or (isomorphic-unfetch)[https://github.com/developit/unfetch/tree/master/packages/isomorphic-unfetch]:

yarn add @wp-headless/client isomorphic-unfetch
import 'isomorphic-unfetch';
import Client from '@wp-headless/client';

const client = new Client('https://demo.wp-api.org/wp-json');

Others

If you would like to use a different transport layer such as axios or superagent you only need to write an adapter that adheres to interface of the Transport class found in the client package. To use this layer pass your custom transport as the second argument to the Client:

import 'isomorphic-unfetch';
import Client from '@wp-headless/client';
import AxiosTransport from 'my-custom-axios-transport';

const transport = new AxiosTransport();

const client = new Client('https://demo.wp-api.org/wp-json', transport);

React

We provide (and reccomend) React hooks that take care of your entire darta fetching life cycle. From fetching initial data, caching, optamistic updates, mutating and refetching - its all covered in an incredibly easy to use hook api. Thanks in a large part to Zeit's swr

Installation

Yarn

yarn add @wp-headless/react

NPM

npm install @wp-headless/react

Usage

import React from 'react';
import { usePost } from '@wp-headless/react';

export const Post = ({ postId }) => {
  const { post, fetching } = usePost(postId);
  return <h1>{post.title.rendered}</h1>;
};

Examples

Examples of usage in a real world application can be found in the examples folder.

Thanks

BrowserStack Logo

Thanks to BrowserStack for lending us their amazing infrastructure to give us automated browser coverage

BrowserStack Logo

Thanks to Drone an incredible pure docker CI/CD platform built on golang for building our stack!

About

Isomorphic Wordpress API client and React hooks - super tiny, super fast.

License:MIT License


Languages

Language:JavaScript 100.0%