Minimizing duplicate routes index.js
$begingroup$
I am trying to build a REST API with express router, which contains of nested sub routes. I have mounted these sub routes in my index.js
file.
I have defined it as follows:
// Mounted routes
app.use('/api/v1/Project', new ProjectRouter().routes);
app.use('/api/v1/Project/:projectId/Context', new ContextRouter().routes);
app.use('/api/v1/Project/:projectId/Context/:contextId/Question', new QuestionRouter().routes);
app.use('/api/v1/Project/:projectId/Context/:contextId/Question/:questionId/Answer', new AnswerRouter().routes);
I want to arrange my routes revolved around the functionality and being more complaint towards REST standards.
In the case the route prefix /api/v1/Project/
is being repeated over and over again.
Is there some best practice to minimize the redundant routes by prefixing?
javascript node.js express.js url-routing
$endgroup$
add a comment |
$begingroup$
I am trying to build a REST API with express router, which contains of nested sub routes. I have mounted these sub routes in my index.js
file.
I have defined it as follows:
// Mounted routes
app.use('/api/v1/Project', new ProjectRouter().routes);
app.use('/api/v1/Project/:projectId/Context', new ContextRouter().routes);
app.use('/api/v1/Project/:projectId/Context/:contextId/Question', new QuestionRouter().routes);
app.use('/api/v1/Project/:projectId/Context/:contextId/Question/:questionId/Answer', new AnswerRouter().routes);
I want to arrange my routes revolved around the functionality and being more complaint towards REST standards.
In the case the route prefix /api/v1/Project/
is being repeated over and over again.
Is there some best practice to minimize the redundant routes by prefixing?
javascript node.js express.js url-routing
$endgroup$
1
$begingroup$
This may be a little ancillary to what you are saying, but it is a common practice to limit the depth of your routes. restful-api-design.readthedocs.io/en/latest/urls.html For instance, you most likely dont need project and context in the url to modify a question's anwser.
$endgroup$
– unflores
Nov 26 '18 at 22:44
add a comment |
$begingroup$
I am trying to build a REST API with express router, which contains of nested sub routes. I have mounted these sub routes in my index.js
file.
I have defined it as follows:
// Mounted routes
app.use('/api/v1/Project', new ProjectRouter().routes);
app.use('/api/v1/Project/:projectId/Context', new ContextRouter().routes);
app.use('/api/v1/Project/:projectId/Context/:contextId/Question', new QuestionRouter().routes);
app.use('/api/v1/Project/:projectId/Context/:contextId/Question/:questionId/Answer', new AnswerRouter().routes);
I want to arrange my routes revolved around the functionality and being more complaint towards REST standards.
In the case the route prefix /api/v1/Project/
is being repeated over and over again.
Is there some best practice to minimize the redundant routes by prefixing?
javascript node.js express.js url-routing
$endgroup$
I am trying to build a REST API with express router, which contains of nested sub routes. I have mounted these sub routes in my index.js
file.
I have defined it as follows:
// Mounted routes
app.use('/api/v1/Project', new ProjectRouter().routes);
app.use('/api/v1/Project/:projectId/Context', new ContextRouter().routes);
app.use('/api/v1/Project/:projectId/Context/:contextId/Question', new QuestionRouter().routes);
app.use('/api/v1/Project/:projectId/Context/:contextId/Question/:questionId/Answer', new AnswerRouter().routes);
I want to arrange my routes revolved around the functionality and being more complaint towards REST standards.
In the case the route prefix /api/v1/Project/
is being repeated over and over again.
Is there some best practice to minimize the redundant routes by prefixing?
javascript node.js express.js url-routing
javascript node.js express.js url-routing
edited Dec 4 '18 at 2:48
Jamal♦
30.3k11116227
30.3k11116227
asked Nov 22 '18 at 10:58
Kunal MukherjeeKunal Mukherjee
1344
1344
1
$begingroup$
This may be a little ancillary to what you are saying, but it is a common practice to limit the depth of your routes. restful-api-design.readthedocs.io/en/latest/urls.html For instance, you most likely dont need project and context in the url to modify a question's anwser.
$endgroup$
– unflores
Nov 26 '18 at 22:44
add a comment |
1
$begingroup$
This may be a little ancillary to what you are saying, but it is a common practice to limit the depth of your routes. restful-api-design.readthedocs.io/en/latest/urls.html For instance, you most likely dont need project and context in the url to modify a question's anwser.
$endgroup$
– unflores
Nov 26 '18 at 22:44
1
1
$begingroup$
This may be a little ancillary to what you are saying, but it is a common practice to limit the depth of your routes. restful-api-design.readthedocs.io/en/latest/urls.html For instance, you most likely dont need project and context in the url to modify a question's anwser.
$endgroup$
– unflores
Nov 26 '18 at 22:44
$begingroup$
This may be a little ancillary to what you are saying, but it is a common practice to limit the depth of your routes. restful-api-design.readthedocs.io/en/latest/urls.html For instance, you most likely dont need project and context in the url to modify a question's anwser.
$endgroup$
– unflores
Nov 26 '18 at 22:44
add a comment |
2 Answers
2
active
oldest
votes
$begingroup$
This is where the Express Router class comes in. You could define a router for ‘api/v1/Project’, mount that router to you main app, and then add the individual routes to the router.
$endgroup$
add a comment |
$begingroup$
The main idea is you can define routes in each controller (no matter how). For hide the base route, you can use a base class with a method addRoute and a property baseRoute or just use a simple variable for base route.
With Ecma6 will look something like this:
in projects.controller.js
require('base.controller.js')
class ProjectsController extends BaseController {
constructor(app){
super(app, "/api/v1/Project");
this.addRoute("/", "get", this.getAll);
this.addRoute("/:id", "get", this.getOne)
}
getAll(){}
getOne(){}
}
module.exports = ProjectsController;
in 'base.controller.js':
class BaseController {
constructor(app, baseRoute){
this.baseRoute = baseRoute;
this.app = app
}
addRoute(route, method, callback){
const url = this.baseRoute + route;
console.log('controllerRoute', url, method);
this.app[method](url, callback.bind(this));
}
}
module.exports=BaseController;
and in index.js (or app/server.js), for each controller:
require("./projects.controller.")(app);
The simplest way:
let baseRoute = "/api/v1/Project";
app.use(baseRoute + "/", new ProjectRouter().routes);
app.use(baseRoute + '/:projectId/Context', new ContextRouter().routes);
$endgroup$
1
$begingroup$
Kunal isn't using TypeScript, and this setup has multiple issues. 1. Method isn't passed toaddRoute
. 2. Nosuper()
call. 3. No nice way to specify another controller is under/api/v1/Project
. 4. Routes are currently looking like/api/api/...
$endgroup$
– Gerrit0
Dec 3 '18 at 4:47
$begingroup$
Yes you are right. I corrected the mistakes. What do you mean by 3. ?
$endgroup$
– Bogdan
Dec 3 '18 at 5:03
$begingroup$
You mean is not ok to define a base class for controller?
$endgroup$
– Bogdan
Dec 3 '18 at 5:11
$begingroup$
About typescript: Ecma6 is very similar with Typescript (except types), so why is this a problem?
$endgroup$
– Bogdan
Dec 3 '18 at 5:15
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208224%2fminimizing-duplicate-routes-index-js%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
This is where the Express Router class comes in. You could define a router for ‘api/v1/Project’, mount that router to you main app, and then add the individual routes to the router.
$endgroup$
add a comment |
$begingroup$
This is where the Express Router class comes in. You could define a router for ‘api/v1/Project’, mount that router to you main app, and then add the individual routes to the router.
$endgroup$
add a comment |
$begingroup$
This is where the Express Router class comes in. You could define a router for ‘api/v1/Project’, mount that router to you main app, and then add the individual routes to the router.
$endgroup$
This is where the Express Router class comes in. You could define a router for ‘api/v1/Project’, mount that router to you main app, and then add the individual routes to the router.
answered 2 hours ago
Mike BrantMike Brant
8,803622
8,803622
add a comment |
add a comment |
$begingroup$
The main idea is you can define routes in each controller (no matter how). For hide the base route, you can use a base class with a method addRoute and a property baseRoute or just use a simple variable for base route.
With Ecma6 will look something like this:
in projects.controller.js
require('base.controller.js')
class ProjectsController extends BaseController {
constructor(app){
super(app, "/api/v1/Project");
this.addRoute("/", "get", this.getAll);
this.addRoute("/:id", "get", this.getOne)
}
getAll(){}
getOne(){}
}
module.exports = ProjectsController;
in 'base.controller.js':
class BaseController {
constructor(app, baseRoute){
this.baseRoute = baseRoute;
this.app = app
}
addRoute(route, method, callback){
const url = this.baseRoute + route;
console.log('controllerRoute', url, method);
this.app[method](url, callback.bind(this));
}
}
module.exports=BaseController;
and in index.js (or app/server.js), for each controller:
require("./projects.controller.")(app);
The simplest way:
let baseRoute = "/api/v1/Project";
app.use(baseRoute + "/", new ProjectRouter().routes);
app.use(baseRoute + '/:projectId/Context', new ContextRouter().routes);
$endgroup$
1
$begingroup$
Kunal isn't using TypeScript, and this setup has multiple issues. 1. Method isn't passed toaddRoute
. 2. Nosuper()
call. 3. No nice way to specify another controller is under/api/v1/Project
. 4. Routes are currently looking like/api/api/...
$endgroup$
– Gerrit0
Dec 3 '18 at 4:47
$begingroup$
Yes you are right. I corrected the mistakes. What do you mean by 3. ?
$endgroup$
– Bogdan
Dec 3 '18 at 5:03
$begingroup$
You mean is not ok to define a base class for controller?
$endgroup$
– Bogdan
Dec 3 '18 at 5:11
$begingroup$
About typescript: Ecma6 is very similar with Typescript (except types), so why is this a problem?
$endgroup$
– Bogdan
Dec 3 '18 at 5:15
add a comment |
$begingroup$
The main idea is you can define routes in each controller (no matter how). For hide the base route, you can use a base class with a method addRoute and a property baseRoute or just use a simple variable for base route.
With Ecma6 will look something like this:
in projects.controller.js
require('base.controller.js')
class ProjectsController extends BaseController {
constructor(app){
super(app, "/api/v1/Project");
this.addRoute("/", "get", this.getAll);
this.addRoute("/:id", "get", this.getOne)
}
getAll(){}
getOne(){}
}
module.exports = ProjectsController;
in 'base.controller.js':
class BaseController {
constructor(app, baseRoute){
this.baseRoute = baseRoute;
this.app = app
}
addRoute(route, method, callback){
const url = this.baseRoute + route;
console.log('controllerRoute', url, method);
this.app[method](url, callback.bind(this));
}
}
module.exports=BaseController;
and in index.js (or app/server.js), for each controller:
require("./projects.controller.")(app);
The simplest way:
let baseRoute = "/api/v1/Project";
app.use(baseRoute + "/", new ProjectRouter().routes);
app.use(baseRoute + '/:projectId/Context', new ContextRouter().routes);
$endgroup$
1
$begingroup$
Kunal isn't using TypeScript, and this setup has multiple issues. 1. Method isn't passed toaddRoute
. 2. Nosuper()
call. 3. No nice way to specify another controller is under/api/v1/Project
. 4. Routes are currently looking like/api/api/...
$endgroup$
– Gerrit0
Dec 3 '18 at 4:47
$begingroup$
Yes you are right. I corrected the mistakes. What do you mean by 3. ?
$endgroup$
– Bogdan
Dec 3 '18 at 5:03
$begingroup$
You mean is not ok to define a base class for controller?
$endgroup$
– Bogdan
Dec 3 '18 at 5:11
$begingroup$
About typescript: Ecma6 is very similar with Typescript (except types), so why is this a problem?
$endgroup$
– Bogdan
Dec 3 '18 at 5:15
add a comment |
$begingroup$
The main idea is you can define routes in each controller (no matter how). For hide the base route, you can use a base class with a method addRoute and a property baseRoute or just use a simple variable for base route.
With Ecma6 will look something like this:
in projects.controller.js
require('base.controller.js')
class ProjectsController extends BaseController {
constructor(app){
super(app, "/api/v1/Project");
this.addRoute("/", "get", this.getAll);
this.addRoute("/:id", "get", this.getOne)
}
getAll(){}
getOne(){}
}
module.exports = ProjectsController;
in 'base.controller.js':
class BaseController {
constructor(app, baseRoute){
this.baseRoute = baseRoute;
this.app = app
}
addRoute(route, method, callback){
const url = this.baseRoute + route;
console.log('controllerRoute', url, method);
this.app[method](url, callback.bind(this));
}
}
module.exports=BaseController;
and in index.js (or app/server.js), for each controller:
require("./projects.controller.")(app);
The simplest way:
let baseRoute = "/api/v1/Project";
app.use(baseRoute + "/", new ProjectRouter().routes);
app.use(baseRoute + '/:projectId/Context', new ContextRouter().routes);
$endgroup$
The main idea is you can define routes in each controller (no matter how). For hide the base route, you can use a base class with a method addRoute and a property baseRoute or just use a simple variable for base route.
With Ecma6 will look something like this:
in projects.controller.js
require('base.controller.js')
class ProjectsController extends BaseController {
constructor(app){
super(app, "/api/v1/Project");
this.addRoute("/", "get", this.getAll);
this.addRoute("/:id", "get", this.getOne)
}
getAll(){}
getOne(){}
}
module.exports = ProjectsController;
in 'base.controller.js':
class BaseController {
constructor(app, baseRoute){
this.baseRoute = baseRoute;
this.app = app
}
addRoute(route, method, callback){
const url = this.baseRoute + route;
console.log('controllerRoute', url, method);
this.app[method](url, callback.bind(this));
}
}
module.exports=BaseController;
and in index.js (or app/server.js), for each controller:
require("./projects.controller.")(app);
The simplest way:
let baseRoute = "/api/v1/Project";
app.use(baseRoute + "/", new ProjectRouter().routes);
app.use(baseRoute + '/:projectId/Context', new ContextRouter().routes);
edited Dec 3 '18 at 17:18
answered Dec 2 '18 at 12:02
BogdanBogdan
12
12
1
$begingroup$
Kunal isn't using TypeScript, and this setup has multiple issues. 1. Method isn't passed toaddRoute
. 2. Nosuper()
call. 3. No nice way to specify another controller is under/api/v1/Project
. 4. Routes are currently looking like/api/api/...
$endgroup$
– Gerrit0
Dec 3 '18 at 4:47
$begingroup$
Yes you are right. I corrected the mistakes. What do you mean by 3. ?
$endgroup$
– Bogdan
Dec 3 '18 at 5:03
$begingroup$
You mean is not ok to define a base class for controller?
$endgroup$
– Bogdan
Dec 3 '18 at 5:11
$begingroup$
About typescript: Ecma6 is very similar with Typescript (except types), so why is this a problem?
$endgroup$
– Bogdan
Dec 3 '18 at 5:15
add a comment |
1
$begingroup$
Kunal isn't using TypeScript, and this setup has multiple issues. 1. Method isn't passed toaddRoute
. 2. Nosuper()
call. 3. No nice way to specify another controller is under/api/v1/Project
. 4. Routes are currently looking like/api/api/...
$endgroup$
– Gerrit0
Dec 3 '18 at 4:47
$begingroup$
Yes you are right. I corrected the mistakes. What do you mean by 3. ?
$endgroup$
– Bogdan
Dec 3 '18 at 5:03
$begingroup$
You mean is not ok to define a base class for controller?
$endgroup$
– Bogdan
Dec 3 '18 at 5:11
$begingroup$
About typescript: Ecma6 is very similar with Typescript (except types), so why is this a problem?
$endgroup$
– Bogdan
Dec 3 '18 at 5:15
1
1
$begingroup$
Kunal isn't using TypeScript, and this setup has multiple issues. 1. Method isn't passed to
addRoute
. 2. No super()
call. 3. No nice way to specify another controller is under /api/v1/Project
. 4. Routes are currently looking like /api/api/...
$endgroup$
– Gerrit0
Dec 3 '18 at 4:47
$begingroup$
Kunal isn't using TypeScript, and this setup has multiple issues. 1. Method isn't passed to
addRoute
. 2. No super()
call. 3. No nice way to specify another controller is under /api/v1/Project
. 4. Routes are currently looking like /api/api/...
$endgroup$
– Gerrit0
Dec 3 '18 at 4:47
$begingroup$
Yes you are right. I corrected the mistakes. What do you mean by 3. ?
$endgroup$
– Bogdan
Dec 3 '18 at 5:03
$begingroup$
Yes you are right. I corrected the mistakes. What do you mean by 3. ?
$endgroup$
– Bogdan
Dec 3 '18 at 5:03
$begingroup$
You mean is not ok to define a base class for controller?
$endgroup$
– Bogdan
Dec 3 '18 at 5:11
$begingroup$
You mean is not ok to define a base class for controller?
$endgroup$
– Bogdan
Dec 3 '18 at 5:11
$begingroup$
About typescript: Ecma6 is very similar with Typescript (except types), so why is this a problem?
$endgroup$
– Bogdan
Dec 3 '18 at 5:15
$begingroup$
About typescript: Ecma6 is very similar with Typescript (except types), so why is this a problem?
$endgroup$
– Bogdan
Dec 3 '18 at 5:15
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208224%2fminimizing-duplicate-routes-index-js%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
$begingroup$
This may be a little ancillary to what you are saying, but it is a common practice to limit the depth of your routes. restful-api-design.readthedocs.io/en/latest/urls.html For instance, you most likely dont need project and context in the url to modify a question's anwser.
$endgroup$
– unflores
Nov 26 '18 at 22:44