Coder Social home page Coder Social logo

lance-rest-client's Introduction

lance-rest-client

Installing

npm install lance-rest-client --save

Simple usage example

var lance = require('lance');

var lance = new Lance({
  baseUrl: 'http://apiserver:3000',
  rootPath: '/v1'
});

lance.initialize().then(function() {
  lance.fetch('people').then(function(people) {
    for (var personIdx in people) {
      var person = people.collection()[personIdx]; 
      console.log(person.get('name'));
    }
  });
});

What's happening under the hood:

  • The client is negotiating with apiserver on port 3000 Root URL /v1
  • The metadata retrieved on that endpoint cointains a link that describe a collection of people
  • lance.fetch('people') gets said collection and returns a promise
  • The people parameter is populated with the instances of people returned by the Lance server

Mapping resources to classes

In order to map Lance resources to client classes. The server's Person class will be mapped to the Person class:

var Person = require('./models/person');

var lance = require('lance');

var lance = new Lance({
  baseUrl: 'http://apiserver:3000',
  rootPath: '/v1',
  modelMap: {
    Person: Person
  }
});

lance.initialize()
  .then(function() {
    return lance.fetch('people');
  })
  .then(function(people) {
    for (var personIdx in people) {
      var person = people.collection()[personIdx]; 
      console.log(person.get('name'), person.skillCount());
    }
  });

This snippet is assuming that ./models/person contains a method such as:

Person.skillCount = function() {
  return this.meta('skillLevels').totalCount());
};

For more details about dealing with collections see section below.

The following example maps all resources in the test:

var lance = require('lance');

var lance = new Lance({
  baseUrl: 'http://apiserver:3000',
  rootPath: '/v1',
  modelMap: {
    Metadata: Metadata,
    Person: Person,
    PeopleCollection: PeopleCollection,
    Skill: Skill,
    SkillsCollection: SkillsCollection,
    SkillLevel: SkillLevel,
    SkillLevelsCollection: SkillLevelsCollection,
    PersonLevel: PersonLevel,
    PersonLevelsCollection: PersonLevelsCollection
  }
});

lance.initialize()
  .then(function() {
    // Your code here
  });

Sending parameters to requests

lance.fetch('person', {
  params: { 
    uuid: '88b4ddfe-e3c1-11e4-8a00-1681e6b88ec1'
  }
})
  .then(function(person) {
    console.log(person.get('name'));
  });

What's happening under the hood:

  • The client is checking for the link for fetching person
  • It will then replace the URI template {uuid} for 88b4ddfe-e3c1-11e4-8a00-1681e6b88ec1 as per spec
  • The response is parsed as a Person object (considering that lance was initialized with it as modelMap)

Updating a resource

lance.fetch('person', {
  params: {
    uuid: '88b4ddfe-e3c1-11e4-8a00-1681e6b88ec1'
  }
})
  .then(function(person) {
      console.log('Previous name:', person.get('name'));
      person.set('name', 'New Person Name');
      return person.save();
  })
  .then(function(updatedPerson) {
    console.log('Confirmed name:', updatedPerson.get('name'));
  });

Deleting a resource

lance.fetch('person', {
  params: {
    uuid: '88b4ddfe-e3c1-11e4-8a00-1681e6b88ec1'
  }
})
  .then(function(person) {
    return person.delete();
  })
  .then(function() {
    console.log('Person deleted');
  });

Adding a resource

lance.create('people', {
  data: {
    name: 'Miles Davis',
    email: '[email protected]'
  }
})
  .then(function(person) {
    console.log(person.get('_id'), person.get('name'));
  });

or, using a Person class:

var miles = new Person({
  name: 'Miles Davis',
  email: '[email protected]'
});

lance.create('people', {
  data: miles
})
  .then(function(person) {
    console.log(person.get('_id'), person.get('name'));
  });

Dealing with collections

lance.fetch('people')
  .then(function(people) {

    // Prints the length of the current page
    console.log(people.collection().length);
  
    // Prints total count of entries, current page number
    // and page count
    console.log(people.totalCount());
    console.log(people.currentPage());
    console.log(people.pageCount());
    
    // Fetches new page and populates the page collection
    return people.nextPage();
  })
  .then(people) {
    console.log(people.currentPage());

    // Fetches the previous page and populates the page collection
    return people.prevPage();
  })
  .then(people) {
    console.log(people.currentPage());
  });

What's happening under the hood:

  • The people collection for the current page is behind collection()
  • totalCount() holds the total amount of resource entries behind this collection
  • currentPage() holds the current page number
  • pageCount() is the total amount of pages
  • nextPage() fetches the next page and populates collection() with its results
  • prevPage() fetches the previous page and populates collection() with its results

Fetching a full representation of a resource

As per Lance-REST spec, sometimes a resource might have been represented in an partial manner. In order to fetch it, let's assume person is already a partial representation of a person:

// i.e. undefined
console.log(person.get('email'));

person.fetchMore()
  .then(function(person) {
    // i.e. [email protected]
    console.log(person.get('email'));
  });

Lance API

constructor({baseUrl, rooPath, modelMap})

  • baseUrl (mandatory): base Url for the server. i.e. http://apiserver:3000
  • rootPath (mandatory): resource path for Lance's root document. i.e. /
  • modelMap (optional): an object mapping Lance class types identifiers to JavaScript classes (instances of BaseModel)

initialize():Promise

GETs and returns the root document as a Model. Binds root document to this Lance instance.

metaModel()

Returns the root document for this Lance instance as a Model.

fetch(linkName, {params, headers}):Promise

  • linkName (mandatory): the URI to GET from. must be a valid member of the _links object.
  • params (optional): URI templating parameters.
  • headers (optional): HTTP headers.

create(linkName, {params, data, headers}):Promise

  • linkName (mandatory): the URI to PUT to. Must be a valid member of the _links object.
  • data (mandatory): object representing the entity to be created.
  • params (optional): URI templating parameters.
  • headers (optional): HTTP headers.

Base Model API

get(field)

Getter for the internal representation of the field (can be dotpath).

set(field, value)

Setter for the internal representation of the field with value (can be dotpath).

meta(field)

Getter for meta fields (inside _meta nodes) (can be dotpath).

fetch(linkName, {headers, params}):Promise

Same as lance.fetch, except _links[linkName] comes from Model instance.

save({headers}):Promise

  • headers (optional): HTTP headers.

Saves the current instance (PUT). Returns the updated resource. Important: the resource must have been fetched before being saved.

delete({headers}):Promfise

  • headers (optional): HTTP headers.

Deletes the current instance (DELETE). Returns Model of server response. Important: the resource must have been fetched before being deleted.

collection()

If the object is identified as a collection, this method returns the current page's collection's array. Otherwise it returns [].

totalCount()

If the object is identified as a collection, this method returns the total amount of entries for this collection beyond the boundaries of the current page (i.e. a collection().length might be 20 while a totalCount() might be 400 - in practice it means that the current page has 20 entries but the collection is 400). Otherwise it returns 0.

currentPage()

If the object is identified as a collection, this method returns the number of the current page (1-based). Otherwise it returns 0.

pageCount()

If the object is identified as a collection, this method returns the amount of pages in this collection. Otherwise it returns 0.

nextPage():Promise

If the object is identified as a collection, this method returns a promise that will get resolved with the next page of the collection. Otherwise it returns false

prevPage():Promise

If the object is identified as a collection, this method returns a promise that will get resolved with the previous page of the collection. Otherwise it returns false

lance-rest-client's People

Contributors

chrisjames-work avatar gaguirre avatar olivier-work avatar

Watchers

 avatar

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.