Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Controller/Route Ordering #782

Closed
dcherman opened this issue Feb 1, 2018 · 1 comment
Closed

Controller/Route Ordering #782

dcherman opened this issue Feb 1, 2018 · 1 comment
Labels

Comments

@dcherman
Copy link

dcherman commented Feb 1, 2018

Given two controllers:

@controller('/');
class MainController() {

  @httpGet('*')
  public async index() {
    this.httpContext.response.render('index.hbs');
  }
}

@controller('/api')
class ApiController {
    @httpGet('/settings');
    public async getIndexSettings() {
      return Promise.resolve({});
    }
}

How do we influence the router ordering such that the API controller serves API requests, and the MainController serves all others for HTML5 routing support?

The controllers are all aggregated and registered internally by inversify, so as far as I can tell, there is no defined way to influence the order in which the routes are registered which is potentially important. A similar issue exists within methods where I want one function to handle something like a / route that maybe redirects to /someDefaultId, but have the * route exist to handle everything else. The ordering of which routes are registered on a method by method basis isn't defined in the inversify API, so I'm not sure how to influence that either.

Thanks!

@remojansen
Copy link
Member

Hi @dcherman thanks for asking. The problem is that you cannot use "" as a child of "/". The routes defined by @controller('/') are joined to the routes defined by methods like @httpGet('*') so it was trying "/". There are two solutions:

A) Using inversify-express-utils

I'm not sure but I think the problem is that you cannot define the "*" as an action you can try the following:

@controller("*")
class NotFoundController {
  @httpGet("/")
  public async index() {
    return Promise.resolve("not found!");
  }
}

@controller("/")
class HomeControllee {

  @httpGet("/")
  public index() {
    return Promise.resolve("home!");
  }
}

const container = new Container();
const server = new InversifyExpressServer(container);
const app = server.build();

app.listen(3000, () => {
  console.log("Listening on port 3000...");
});

b) Using express.js

const server = new InversifyExpressServer(container);

// Info: https://github.com/inversify/inversify-express-utils/blob/752a68310e3ea515c0c47a757413fe38ee1f00f4/src/server.ts#L71-L82
server.setErrorConfig((app) => {
    // Catch and log all exceptions
    app.use(exceptionLoggerMiddleware);
});

// Info: https://github.com/inversify/inversify-express-utils/blob/752a68310e3ea515c0c47a757413fe38ee1f00f4/src/server.ts#L58-L69
server.setConfig((app) => {
    app.use(helmet());
});

// Loads constrollers and initializes routing
const app = server.build();

// The route for /
app.get("/", (req: express.Request, res: express.Response) => {
    res.redirect(homePath);
});

// The last route should be a global handler for 404 errors
app.get("*", (req: express.Request, res: express.Response) => {
    res.redirect(notFoundPath);
});

This should solve your problem so I'm closing the issue. Please feel free to ask again if you need additional help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants