I assume you are expecting your site have a large amount of traffic. If that assumption is correct, I would say go with a tweaked version of Implementation 3.
If api.site.com and gateway.site.com are on two different servers, I would also have a third server to house the DB and have both apps leverage the centralized DB. This will eliminate the need for api.site.com and gateway.site.com to even know about each other and keep all work in a designated area, making any debugging that much easier.
And if my assumption is incorrect, I'd say go a differently tweaked version of Implementation 3. So you'd build you two separate apps that communicate with the same Db, and simply house everything on the same server. Which is basically what I just said above but all on the same server. This should reduce initial overhead and make scaling a breeze when the time comes.
Disclaimer
Despite the question has been scoped as REST, the truth is that it has nothing to do with REST.
Long story short, how to map the request parameters to an specific query language is implementation details. So, for now, lets leave REST aside.
Is the above implementation/concept correct?
For us to say whether is correct or not, we would need to be familiar with the project and its requirements. So far, what we can say is: the solution is not flexible.
Flexible in the sense of scaling in the long run. Every new filter
would take you (at least) to modify the controller
, the service layer and maybe the data access layer too. From the management standpoint, is hard to buy so much work for so little feature. In other words, the maintenance looks expensive.
Nevertheless, it depends on how often you add new parameters to the query.
So what am I doing wrong here?
You are missing two possible abstractions.
- The one that maps a dynamic set of request parameters to an specific model of the API.
- The one that maps the previous model to your specific query language.
Note: Some frameworks makes #1 optional.
Right now the mapping is hardcoded as a if/else
block. Too rigid for scaling well.
Instead, It could be similar to:
myController(req,res){
var query = new QueryParametersMapper(req);
var page = new PageParametersMapper(req);
var sort = new SortParametersMapper(req);
var dataSet = myRepository.find(query, page, sort);
// etc...
}
What's the correct way of handling queries?
Making the mapping more dynamic and reusable.
At this point, my first advice would be look for libraries compatible with your framework or programming language.
My second advice would be, pick the one that supports Convention over configuration.
Even if It doesn't prevent you from making changes, at least (I'm sure) the costs of the changes will be lesser than they are now.*
* If we consider the code given as example in the question.
Best Answer
In general, you could prefix everything with some prefix, such as /api
This makes sense for example when there are different kinds of APIs. if this is not intended, why should you choose such an approach?
We are in a similar discussion, we go for:
as acces paths for different accesses and devices. Then, under this, we have the resources used by the access paths.
As your request is not very detailed, I would rather go for
/posts
/payments
Keep in mind, a stateless design is very helpful.