D
D
dizlv2014-10-26 15:20:17
JavaScript
dizlv, 2014-10-26 15:20:17

How to properly organize DRY architecture for REST back-end?

There was a need to write a client in AngularJS to interact with the REST API in Django (Django Rest Framework). Restangular was chosen as the framework for AngularJS . Each endpoint has its own service and 2 controllers (ObjectNameListController and ObjectNameDetailController). The thing is that services and controllers have an identical structure, and I wanted to move all the common code into parent services and controllers. But I still can't think of the best way.
I tried to put it into directives (the directive has its own controller to which the service is passed through an attribute):

function RESTSupportDirective() {
    return {
        restrict: 'E',
        controller: function($scope, $injector) {
            var self = $scope;

            self.objects = [];

            self.activate = function (serviceName) {
                self.service = $injector.get(serviceName);
            };

            self.list = function () {
                self.service.list().then(function (response) {
                    self.objects = response;
                }, function (error) {

                });
            };

            self.create = function (newObject) {
                self.service.create(newObject).then(function (response) {

                }, function (error) {

                });
            };
        },
        link: function (scope, element, attrs) {
            scope.activate(attrs.serviceName);
        }
    };
}

But with this approach, I don't see a way to use routing (resolve).
The second implementation is to initialize the controller directly in the routing using resolve:
function getService(serviceName) {
    return {
        service: [serviceName, function (serviceName) {
            return serviceName;
        }]
    };
}
// Routing
$routeProvider.when('/object', {
    templateUrl: '',
    controller: 'RESTListController',
    controllerAs: 'objectController',
    resolve: getService('ObjectService')
})

// Controller
function RESTListController(Service) {
    var self = this;

    self.objects =  [];

    self.list = function () {
        console.log(Service);
        Service.list().then(function (response) {
            self.objects = response;
        }, function (error) {

        });
    };

    self.create = function (newObject) {
        Service.create(newObject).then(function (response) {

        }, function (error) {

        });
    };
}

Here the question arises - how to pass service if you do not use routing with resolve?
In general, a service and controller has a set of list() , one() , create() , and remove() methods. Any ideas how to put this in the parent function "correctly"?
PS. I considered examples with inheritance, but for some reason nothing started.
P.P.S. I don't use $scope, just "this" approach.
Thank you.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
Sergey, 2014-10-26
Protko @Fesor

I somehow experimented with inheritance of controllers and came to the conclusion that if you have code duplication in the controller, which is beautifully solved by inheritance ... then something went wrong and this matter should be moved to services.
Next, it makes sense to use UI-Router to separate screens into separate states. Common things can be taken out to the base states in this way and achieve more flexibility ...
I also do resolv something like this:

$stateProvider.state({
    resolve: {
       list: function (service) {
            return service.list();
       }
    },
    controller: function (list) {
       this.list = list;
    }
});

When separated into separate states with some kind of hierarchy, child states can use parent resolvers... inherit and override controllers, etc.
It's kind of chaotic... and I'd also be curious to see other people's approaches.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question