Skip to content

Instantly share code, notes, and snippets.

@seyDoggy
Last active September 4, 2016 05:29
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save seyDoggy/43842c9ceb176a2ba0728f9409c00dd0 to your computer and use it in GitHub Desktop.
Save seyDoggy/43842c9ceb176a2ba0728f9409c00dd0 to your computer and use it in GitHub Desktop.
An AngularJS RESTful Constructor
/**
* @ngdoc module
* @name Restful
* @description
*
* Restful is a base class from which to extend and create more CRUD services
* without the need to repeat the same CRUD operations and implementation
* with each additional service.
*
* The Restful factory takes one argument, a configuration object.
*
* The Restful factory is used in the creation of a new service that requires
* standard CRUD methods. For instance, if you want to make a service that
* reads a list of folders from 'someapi/v1/folders', you create a new
* AngularJS service with 'Restful' injected into it. Then you'd return a new
* Restful object with the path 'folder' and the method 'read'.
*
* @param {object} config A configuration object with two properties:
* @param {string} config.path The final path to the rest endpoint, after
* the default RESTAPI constant.
* @param {string=|array=} config.methods An optional property that, if
* present, it will reflect the methods required in your restful
* service. The property can contain any combination of 'create',
* 'read', 'update' and 'destroy'. If the 'method' property is omitted
* then all CRUD methods will be available to your new service.
*
* @return {object} Newly created object containing one or more methods:
*
* - `{{*}}` `create({object} data, {object} config)`
* - `{string}` `read({string} id)`
* - `{{*}}` `update({string} id, {object} data, {object} config)`
* - `{string}` `destroy({string} id)`
*
* @example
*
* Typical usage if all CRUD operations are desired:
*
* ```js
* angular
* .module( 'myApp', [ 'Restful' ] )
* .factory( 'userService', function (Restful) {
* return new Restful( { path: 'users' } )
* })
* .controller( 'UserController', function (userService) {
* var vm = this;
* vm.user = void 0;
* userService.get('1234')
* .then( function () {
* vm.user = response.data;
* });
* })
* ```
*
* If only the read option is required:
*
* ```js
* angular
* .module( 'myApp', [ 'Restful' ] )
* .factory( 'userService', function (Restful) {
* return new Restful( { path: 'users', methods: 'read' } )
* })
* .controller( 'UserController', function (userService) {
* var vm = this;
* vm.user = void 0;
* userService.get('1234')
* .then( function () {
* vm.user = response.data;
* });
* })
* ```
*
* If read and update options are required:
*
* ```js
* angular
* .module( 'myApp', [ 'Restful' ] )
* .factory( 'userService', function (Restful) {
* return new Restful( { path: 'users', methods: [ 'read', 'update' ] } )
* })
* .controller( 'UserController', function (userService) {
* var vm = this;
* vm.user = void 0;
* userService.get('1234')
* .then( function () {
* vm.user = response.data;
* });
* userService.update('1234', { name: 'Adam Merrifield', occupation: 'developer' })
* .then( function () {
* vm.user = response.data;
* });
* })
* ```
*
*/
(function() {
'use strict';
/**
* RESTful base class
*
*/
angular
.module('Restful', ['$http'])
.constant('RESTAPI','http://some.api/v1/')
.factory('Restful', Restful);
/** @ngInject */
function Restful($http, $log, $q, RESTAPI) {
var RestfulService = init,
methods = {
create: create,
read: read,
update: update,
destroy: destroy
};
return RestfulService;
/**
* @ngdoc constructor
* @constructs Restful.Restful#init
* @description
*
* Initializes a new Restful object with any or all of the CRUD methods
*
* @param {object} config Contains `path: 'String'` and `methods: [Array]`
* @returns {Object} An object instance of type Restful
*/
function init(config) {
this.url = RESTAPI;
if (config && angular.isObject(config)) {
if (config.path) {
this.url += config.path;
}
if (config.methods && angular.isArray(config.methods)) {
for (var i = 0; i < config.methods.length; ++i) {
this[config.methods[i]] = methods[config.methods[i]];
for (var prop in methods) {
if( methods.hasOwnProperty( prop ) && !this[prop]) {
this[prop] = notSupported(prop);
}
}
}
} else {
for (var prop in methods) {
this[prop] = methods[prop];
}
}
}
}
/**
* @ngdoc method
* @constructs Restful.Restful.create
* @description
*
* Abstraction for $http.post()
*
* @param {object} data A payload object to send to the server
* @param {object} config An object containing any $http configurations
* @returns {Object} A promise
*/
function create(data, config) {
if (data) {
if (config) {
return $http.post(this.url, data, config);
}
return $http.post(this.url, data);
}
return $q.when("No payload provided.")
}
/**
* @ngdoc method
* @constructs Restful.Restful.read
* @description
*
* Abstraction for $http.get()
*
* @param {string} id The optional id to fetch from the server when selecting one item, otherwise all items are returned.
* @returns {Object} A promise
*/
function read(id) {
if (id) {
return $http.get(this.url + id);
}
return $http.get(this.url);
}
/**
* @ngdoc method
* @constructs Restful.Restful.update
* @description
*
* Abstraction for $http.put()
*
* @param {string} id The id to update from the server
* @param {object} data A payload object to send to the server
* @param {object} config An object containing any $http configurations
* @returns {Object} A promise
*/
function update(id, data, config) {
if (id && data) {
if (config) {
return $http.put(this.url + id, data, config);
}
return $http.put(this.url + id, data);
}
return false;
}
/**
* @ngdoc method
* @constructs Restful.Restful.destroy
* @description
*
* Abstraction for $http.delete()
*
* @param {string} id The id to delete from the server
* @returns {Object} A promise
*/
function destroy(id) {
if (id) {
return $http.delete(this.url + id);
}
return false;
}
/**
* @ngdoc function
* @constructs Restful.Restful#notSupported
* @description
*
* Error handler for unsupported methods
*
* @param {string} mthd The method that is not supported by a particular instance of the class
* @returns {Object} A promise
*/
function notSupported(mthd) {
return function () {
return $q.reject('The Restful method, ' + mthd + '(), is not supported for this instance of the Restful Service.');
}
}
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment