npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

redux-rest

v0.0.1-alpha.9

Published

Create Redux action constants, action creators and reducers for your REST API with no boilerplate.

Downloads

92

Readme

Build Status

redux-rest

NOTE this requires redux 1.0.0-rc or above

NOTE POST/PUT requests currently tied to Django Rest Framework's CSRF handling and response content

Create Redux action constants, action creators and reducers for your REST API with no boilerplate.

Install

npm install redux-rest

Example

import React from 'react';
import { connect, Provider } from 'react-redux';
import { createStore, combineReducers, applyMiddleware } from 'redux';
import thunkMiddleware from 'redux-thunk';
import API from 'redux-rest';


// This is a super simple app that displays a list of users from an API and
// lets you add new users. Until a success response is recevied from the API
// endpoint new users are show as pending.

// To create a store with redux for this app all you have to do is
// describe your API endpoints as key value pairs where the key is an
// identifier and the value is the URL of the endpoint.
const myAPI = {
  users: '/api/users/'
};

// Then create an API instance. This automatically creates
// action creators and reducers for each endpoint. No boilerplate!
const api = new API(myAPI);

// UserApp uses the api object to fetch the users and create new ones
// using the automatically created action creators.
class UserApp extends React.component {

  componentDidMount() {
    // Request the list of users when this component mounts
    this.props.dispatch(api.actionCreators.users.list());
  }

  render() {
    let users = this.props.users;
    let pendingUsers = users.filter(u => u.status === 'pending');
    let currentUsers = users.filter(u => u.status !== 'pending');
    return (
      <div>
        {pendingUsers.map(user => <p>Saving {user.username}...</p>)}
        <ul>
          {currentUsers.map(user => <li>{user.username}</li>)}
        </ul>
        <input ref="username" placeholder="Enter username"/>
        <input type="submit" value="Add user" onClick={this._addUser}/>
      </div>
    );
  }

  _addUser() {
    let inputNode = React.findDOMNode(this.refs.username);
    let val = inputNode.value;
    this.props.dispatch(
      api.actionCreators.users.create(
        {username: val}
      )
    );
    inputNode.val = '';
  }
}

// The api object also has reducers to handle the standard REST actions
// So we can configure redux and connect our UserApp to it.
let reducers = combineReducers(api.reducers);

// To integrate with redux we require the thunk middleware to handle
// action creators that return functions.
let createStoreWithMiddleware = applyMiddleware(
  thunkMiddleware
)(createStore);

let store = createStoreWithMiddleware(reducers);

// Which props do we want to inject, given the global state?
function select(state) {
  // Each endpoint has an _items and _collection reducer. Here we only need
  // the user items so we only pull out users_items.
  return {
    users: state.users_items
  };
})

// Wrap UserApp to inject dispatch and state into it
UserApp = connect(select)(UserApp);

export default class App extends React.Component {
  render() {
    // To render UserApp we need to wrap it in redux's Provider.
    return (
      <Provider store={store}>
        {() => <UserApp />}
      </Provider>
    );
  }
}

What is the api object?

The api object encapsulates common patterns when dealing with REST APIs.

When created with a description of your API you can call all the actions you'd expect and there are reducers that automatically handle those actions, including 'pending', 'success' and 'failure' states.

import API from 'redux-rest';

const myAPI = {
    users: '/api/users/',
}	   

const api = new API(myAPI);

This creates a pair of reducers for each API endpoint; a collection reducer to handle actions at the collection level and and item reducer to handle actions on individual items.

TODO not sure about the item/collection stuff. Needs a rethink.

Calling actions is as simple as

api.actionCreators.users.create(userData);

Status of API requests

Each action creator triggers an API request and immediately dispatches an action so the UI can reflect the change straight away. During the request the state change is marked as pending. For example, creating a new object,

api.actionCreators.users.create({username: 'mark'});

will add,

{
    username: 'mark',
    status: 'pending'
}

to the state.

TODO what if 'status' is already a field of user?

On completion of the request the status is updated to saved or failed as appropriate. E.g.

{
    username: 'mark',
    status: 'saved'
}

Available actions

The standard set of REST actions is available; list, retrieve, create and update.

TODO

  • add delete action
  • add a revert action to revert optimistic changes if API request fails.
  • support APIs with custom endpoints
  • integrate normalizr for flat object storage?