0

I'm using Angular's $resource service to make calls to a RESTful web service. Currently I'm doing this:

app.factory('data', function($resource) {
    // Creating resource objects for all resources I have.
    var usersResource = $resource('http://example.com/api/users/:id', {id: '@id'});
    var universitiesResource = $resource('http://example.com/api/universities/:id', {id: '@id'});
    // ..
    // Initializing more resource objects.

    return {
        users: {
            getAll: function() {
                return usersResource.query();
            }
            // ..
            // More methods..
        },
        universities: {
            getAll: function() {
                return universitiesResource.query();
            }
            // ..
            // More methods..
        }
        // ..
        // More objects.
    }
});

The other way is to have a different data factory for every resource. So, my question is what's the proper way of doing this and why? It looks more structured to have just a single data factory, but are all these resource objects making a lot of burden and reducing the performance of the app?

1

1 Answer 1

2

Your way looks ok if your application not so big and you will not have dozens of resources collected in one place. If so this "global data factory" will be too big and everyone in your team will edit it constantly. One more consideration - your resources usually more complex then just plain CRUD operations. You have to extend them with additional functions like described in the official docs:

var CreditCard = $resource('/user/:userId/card/:cardId', {userId:123, cardId:'@id'}, {
  charge: {
         method:'POST', 
         params:{charge:true}
   }
 });

Imagine how it will look like if you will put every declaration like this in one place.

I came up to the different approach - to make resources available on demand and even not declare them in case of default CRUD operations. We have the following factory:

angular.module("app").factory("resourcesByConvention", ResourcesByConvention);

ResourcesByConvention.$inject = ['$injector', '$resource'];
function ResourcesByConvention($injector, $resource) {
    return {
        getResource: function (resourceName) {
            var resource;
            try{
                resource=$injector.get(resourceName);
            }
            catch(error)
            {
                resource = $resource('/api/' + resourceName, {}, {
                    update: {
                        method: 'PUT'
                    }
                });

            }
            return resource;
        }
    }
}

In every place we injecting this factory and doing:

var usersResource=resourcesByConvention.getResource("users");

If you need only simple CRUD operations for your resource - this factory will just create it for you. But if you need some more complex, you just create and register your own. For example, you will register the following:

app.factory('AccountResource', ['$resource', function($resource) {
return $resource('/account/:id', null,
    {
        update: { method:'PUT' },
        getBalance: {method: 'GET'},
        charge: {method: 'POST'}
    });
}]);

and request it later:

var accountResource=resourcesByConvention.getResource("AccountResource");

Conclusion: you have single service to get any resource needed and you may not declare typical CRUD resources at all.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.