Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free.

As title: Why is aggregation function bad idea for RESTful? Although I know CRUD is good for RESTful.

For example, the resource is 'employee', and client needs to retrive sum of total 'salary' of all employees. Shouldn't RESTful service provide such sum function?

Further question: if aggregation function is bad for RESTful, how can a client get sum of total salary? To retrieve all 'employee' records and sum up itself?

share|improve this question

closed as primarily opinion-based by gnat, GlenH7, amon, MichaelT, Bart van Ingen Schenau Sep 19 '14 at 12:11

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.

See my answer here programmers.stackexchange.com/questions/204458/… In short, functions shouldn't exist in REST. Create a SOAP service in which you pass in the resource ids, etc. –  Andrew Finnell Jul 17 '13 at 12:42
I just created a new term... REST-RPC. And as the creator, I hereby declare that if you want to pull back aggregate data or trigger actions on a server using a simple http request rather than getting into the muck that is SOAP, you are approved, and are still properly adhering to REST-RPC principles. I also declare that peanut M&M's are the best kind of M&M's. –  GrandmasterB Jul 17 '13 at 21:45
"avoid asking subjective questions where … your question is just a rant in disguise: “______ sucks, am I right?”" (help center) –  gnat Sep 18 '14 at 14:37

3 Answers 3

Why is aggregation function bad idea for RESTful? Although I know CRUD is good for RESTful.

I don't know where you heard that, but that is not true.

For example, the resource is 'employee', and client needs to retrieve sum of total 'salary' of all employees.

You can use the following request: GET /total-salary-of-all-employees and add a custom link relation.

share|improve this answer


If by "aggregation function" you mean something like:

SUM /employee-salary

then it would be bad because it would add a specific verb into an architecture whose limited list of standard verbs is one of its big advantages.

Almost always when you are trying to force a verb (average, transfer, ...) on a REST interface, there is a hidden resource lurking somewhere.

To get into a better REST style stop the verb thinking that comes from RPC (Remote procedure call) and start thinking resources. The aggregations you are talking about in REST are better exposed as attributes of a department and/or manager and/or company resource.

I strongly recommend reading RESTful web services. I think you will find the information about the differences between REST and RPC as well as all the information about resource and URI discovery very useful.

Aggregated data

If by "aggregation function" you mean you want some way to have the service return aggregated results, then there is nothing in REST that says you can't.

How can a client get sum of total salary?

The sum total of salaries for whom? The company? A department? A manager that is involved with two departments? Wouldn't the company, the department or the managers be resources in their own right? Each with a number of employees "under" them?

Attribute on other resources

Giving the client access to the list of employees for these resources could be one way of allowing them to sum the salaries themselves. But that could pose all kinds of privacy and authorization issues. So maybe it would be better if the company, department and manager resources simply provided a "total_salary" attribute that would be calculated by the service.

Algorithmic URI

Another approach is what "RESTful web services" refers to as "algorithmic URI's".

Algorithmic URI's are URI's just like the one in @inf3rno's answer:

GET /total-salary-of-all-employees

@inf3rno's URI, however, is very, very specific. What if I would like to get the total salary of the employees in the "data-entry" and "secretarial support" departments? Or of all employees who have been with the company for more than x years?

I would probably go for a set of URI's along the following lines:

GET /payroll
GET /payroll/department/{ids}
GET /payroll/employee/{ids}

where {ids} stands for one or more identifiers.

In this set the main /payroll URI provides the "grand-total" for the company. The /department sub scope provides the means of filtering employees to be included in the numbers by department, while the /employee sub scope allows for grouping the numbers of employees based on other selection criteria.

The list of identifiers for the department and employee sub scopes would have been gotten in previous GET's to other URI's. For example a GET on the /employees URI with something like ?started-before=201006 to get all employees that started with the company before June 2010.

These URI's could by default provide the numbers of the last payroll-run, or what the company needs to pay out in the next one.

To get the numbers for a specific period (or payroll run) the URI's could be made to support a "period" query parameter:

GET /payroll/department/{ids}?period={from}-{to}


GET /payroll/department/1,15,17?period=2014     // 2014 total for these 3 departments
GET /payroll/employee/35,21?period=201401       // Jan 2014 for these 2 employees
GET /payroll?period=201404-201406               // Second quarter 2014 for company

The body of the resource that is returned could by default contain all numbers that are of interest in a payroll system. To narrow the information (and reduce the load on the server perhaps?) a "fields" parameter could be supported:

GET /payroll/employee/{ids}?fields={fieldnames}


GET /payroll/employee/5,39?fields=gross,net,deductibles

And combining the supported query parameters:

GET /payroll/department/200?period=201401-201403&fields=gross,net,deductibles
share|improve this answer
Projection and aggregation have nothing to do with RPC. It's is something that greatly enhances any queryable system and if done on the server side can greatly help reduce resource consumption. And yes, total salary is something that could belong to a department. But what if I want the average salaries depending on age group, sex, academic level. Should that be a property of the department? And the company? And every section? –  back2dos Jul 17 '13 at 18:19
@back2dos: nope, not necessarily. However, the flexibility you are seeking is not something that is solved by verbs either. The resource you are looking for is the payroll with a number of attributes and several query parameters in what the "RESTful web services" book calls algorithmic resources. /payroll/salaries/average/female/40;45/masters/ comes to mind. Or if you want /payroll/salaries/average?sex=female&agegroup=40-45&academiclevel=masters. Still no need for verbs! –  Marjan Venema Jul 17 '13 at 19:01
Ok, so rather than having a verb, I have nouns that represent an action? How is that better? In fact I would claim that such a system has significantly worse discoverability. What if I want the average ages per position type? Or the number of employees for each initial letter? SQL can do it, most document stores can do it. And all without having to add any further pseudo-entities to the domain model, just because somebody may need them. It's not uncommon to allow specifying return fields and even their format in "RESTful" APIs. Adding aggregation on top of that is only the next logical step. –  back2dos Jul 17 '13 at 20:14
Ok, then please tell me what a POST to /payroll/salaries/average resource does? You are forcing your self to a ridiculously small feature set and are then bending it enormously to suit your needs. And are you seriously claiming that if I list all /employees/ I should be finding a link to /payroll/salaries/average/ (which seriously from the parameters it accepts is more a remote procedure instead of a resource). That means that for every "algorithmic resource" I would have to have a link from the underlying resources. This simply doesn't scale. –  back2dos Jul 18 '13 at 9:48
@back2dos: nothing of course. You don't need to provide all HTTP verbs for all resources. Most algorithmic resources would only offer GET. And no you don't need to provide links for everything as long as the query parameters for a resource are known. There are many ways to approach this. As I said: read up on REST, preferably with the book I mentioned in my answer, and stop knocking REST just because you don't understand it yet. –  Marjan Venema Jul 18 '13 at 9:51

I know CRUD is good for RESTful.

Wrong, CRUD is very far from REST; typically separated at least by 2-3 layers of abstraction.

The point is: REST doesn't deal with database records, it handles resource representations.

Now, what's a resource? is it a database record? no, it's not. It's a more extensive, abstract concept. Resources in a system can be User profiles, activities, documents, statistics, etc.

In your example, you have an employee resource, I guess there's also a division resource, which can list the related employees. Maybe also an enterprise resource, which contains divisions. But there could also be a middle managers resource, with employees from all divisions.

Any of these "grouping" resources should have a link to the list of "contained" resources, and also some other attributes, like full name, a longer description, maybe an address, etc. Also there could be links to other "complementary" resources, like a webpage, a document repository, etc. Among those, there could be a "statistics" resource, with all the aggregations you want, either as prespecified fields, or via some specifications in the URI.

share|improve this answer
You seem to have inferred that CRUD somehow meant database. REST is accessed through the HTTP CRUD verbs GET, Post, put and delete. –  Andrew Finnell Jul 17 '13 at 14:40
from wikipedia "create, read, update and delete are the four basic functions of persistent storage." So, yes, CRUD is the database. Get, post, put and delete do not simply create records, they handle representations. (which can be made to correspond 1:1 with records, but that's just one limited use) –  Javier Jul 17 '13 at 14:42
@Javier CRUD is a concept, not directly tied to databases, which contains the verbs READ, CREATE, DELETE, UPDATE. Databases implement it with the verbs SELECT, INSERT, DELETE, and UPDATE. REST implements it with the verbs GET, POST, DELETE, PUT. They are not separate concepts, but closely interrelated. –  Izkata Jul 17 '13 at 16:06
"Persistent storage" does not necessarily mean 'database'. It could be a file-store, or any other mechanism to persist resources. –  Eric King Jul 17 '13 at 16:20
@EricKing. right, any mechanism to persist records, but resources, as defined for REST, are other thing, not necesarily persistent records (ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm, part –  Javier Jul 17 '13 at 17:13

Not the answer you're looking for? Browse other questions tagged or ask your own question.