Coder Social home page Coder Social logo

consumerjs's Introduction

Build Status Coverage Status Code Climate

NPM Sauce Test Status

ConsumerJS

Consumerjs simplifies REST with an ORM like approach. Built on top of Axios.

Consumerjs is an ORM-like repository/entity mapper that aims to make using RESTful JSON API's simple and DRY. It supports basic CRUD operations on remote resources and can easiy be extended with custom behaviour.

ConsumerJS out of the box supports (Django) CSRF protection.

Installation

Install with npm.

$ npm i consumerjs --save

As of 2.0.0: @babel/polyfill needs to be installed in your project in order to support older browsers like Internet Explorer 11.

Usage

See doc for full API documentation.

Example:

data/post.js

import { CrudConsumer, CrudConsumerObject } from 'consumerjs';


class Post extends CrudConsumerObject {}


class PostConsumer extends CrudConsumer {
    constructor(endpoint='http://example.com/api/v1/posts/', objectClass=Post) {
        super(endpoint, objectClass);
    }
;}


export default PostConsumer;

examples/my-app.js

import PostConsumer from '../data/post.js';


let postConsumer = new PostConsumer();
postConsumer.create()
    .then(someFunction)  // When promise resolves, call someFunction with new Post object
    .catch(errorFunction);  // When promise rejects, call errorFunction

    
//
// When a consumer receives a JSON array as result, an array of consumer objects is returned.
//

    
postConsumer.read()
    .then(someFunction)  // When promise resolves, call someFunction with all resolved Post objects
    .catch(errorFunction);  // When promise rejects, call errorFunction
    
    
let id = 1;
postConsumer.read(id)
    .then(someFunction)  // When promise resolves, call someFunction with resolved Post (with id 1)
    .catch(errorFunction);  // When promise rejects, call errorFunction

examples/my-app2.js

// Internally, id is resolved using either "pk" or "id" field

post.title = 'some new title';
post.update()  // Saves changed fields to API using partial PATCH request
post.save()  // Save all fields to API using full PUT request
post.delete()  // Deletes this post using DELETE request

Pagination

TODO: Document the usage of various List types and pagination. For now please see the tests for examples.

Concepts

ConsumerJS defines a few built-in classes, all of those should preferably be extended by a custom class implementing domain specific behaviour (if any):

Consumers (Consumer, CrudConsumer):

"Consumers" are classes that define how to perform operations on the remote API. It converts the results to "Consumer object" which contains a statefull representation of the API result.

A consumer:

  • Acts a data store fore fetching remote data.
  • Can be used to convert human readable methods into DELETE, GET, PATCH POST and PUT requests.
  • All requests return promises.
  • Successfull API requests return promises for either an array (list) or a single consumer object (scalar).
  • Failed API requests cause the promise to reject.
  • Objects are cast to instances of a configurable consumer object class referenced by the consumers "objectClass" key.

Consumers should be preferably be extended, configured and optionally, methods can be overwritten to change default behaviour. Configuration should preferably be done in de constructor method:

/**
 * Configures Consumer instance
 * @param {string} endpoint Base endpoint for this API
 * @param {AbstractConsumerObject} objectClass Class to cast results to
 * @param {Object} [options] Additional configuration
 */
constructor(endpoint='http://example.com/api/v1/posts/', objectClass=Post, options=null) {
    super(endpoint, objectClass);
}
  • Consumer: Simple "bare" consumer intended for use with custom methods.
  • CrudConsumer: "Consumer with base methods for common CRUD operations.
    • create([object]), creates objecs.
    • read([id]), fetches all objects or a single object by id.

Consumer objects (ConsumerObject, CrudConsumerObject):

"Consumer objects" are classes that define how to perform object specific operations on the remote API. Consumer objects should be extended, configured and optionally methods can be overwritten to change default behaviour.

A consumer object:

  • Is the result of a resolved promise, gets passed to the promise's then() method.
  • If the API returns an array (list), an array of object classes is returned.
  • If the API returns a single object (scalar), a single object is returned.
  • The consumer object class can have methods.
  • The consumer object class keeps a reference to it's consumer using the "_consumer_" key, this allows methods to talk back to the API.

A reference to the consumer is kept using the __consumer__ property, (custom) methods can use this to communicate with the API.

customMethod(data) {
    return this.__consumer.__.post('/path/', data);  // CrudConsumerObject instances can use this.getPath() as path.
}
  • ConsumerObject: Simple "bare" consumer object intended for use with custom methods.
  • CrudConsumerObject: "Consumer object with base methods for common CRUD operations.
    • update(), persists changes made to object.
    • save(), fully saves object.
    • delete(), deletes this object.

consumerjs's People

Contributors

clarity-89 avatar dependabot[bot] avatar sergei-maertens avatar svenvandescheur avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

clarity-89

consumerjs's Issues

Support request cancellation

In my use-case I'm using consumerjs to fetch search results based on a number of filters, in a React application. I already de-bounce events, but it happens that a request fires and another search-query is performed before the previous request finishes (thumbnailing on my dev-machine is slow ;) ).

This messes up my component, as the earlier request now overwrites the results from the current search because of the long request time (10s vs 2s for example).

To combat this, I want to be able to cancel the old request. Axios supports this, so this interface should maybe be exposed in ConsumerJS too? See https://github.com/axios/axios#cancellation

Circular structure error when serializing consumer object

__consumer__ property on consumer object causes circular structure error when manually serializing it (for example when saving data to local storage).

Error:

Uncaught TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'CourseConsumer'
    |     property 'client' -> object with constructor 'e'
    --- property 'consumer' closes the circle

Implement pagination

This needs te be thought out more clearly, probably would require lists to return a custom type that extends the Array prototype and holds page state related information.

The implementation needs to be generic and not specific for any framework like Django REST. Maybe we should allow something like a pagination class in consumers...

Add CORS-ability

To be able to make CORS-requests, we should be able to pass the withCredentials: true to axios-requests. This is currently not possible, because consumerjs/axios-http-client cannot be imported to subclass it. This should probably be an option on the abstract-consumer.

Use case:

  1. Run backend server (Django) on http://localhost:8000
  2. Log in - session cookie is set
  3. Run a docker-compose set up on http://localhost
  4. Try to make an authorized request from http://localhost Javascript to http://localhost:8000 and observe that the cookies are not sent.

HTTP 204 errors

ConsumerJS expects JSON, while HTTP 204 returns an empty body. This is the case for DELETE requests.

Client needs to be loose coupled and hot swappable

Currently, the consumers (this).client is always an instance of the Aurelia http client. This needs to be abstracted so different clients can be used and configured (e.g. a fetch client).

  • Specify the client interface
  • Abstract the current client interface
  • Optionally implement a node.js compatible data client

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.