Custom middleware(routing) to discriminate URL parameters

Ok, great. So those will work fine, without the middleware? I just now need to implement the above as per my structure. I’m going to try this today!

1 Like

With the middleware and without it of course.

1 Like

@JonL - a couple of questions if you don’t mind.

So, the param options I have are:

Industry, Function, Country, State, City, Service.

Am I on the right path here with some edits I’ve made? (I’m a total novice with this). One question, with country/state/city and even industry/function - the available params are in the 10’s of thousands, I can’t input them all manually in here, so would I do a query first to output the results and then use a data binding in there?

If it helps, an example (most extreme) url path (ideal scenario) could be: recruiters/construction/sales/united-states/california/san-francisco/retained for example.

 const { templateView } = require('../../../lib/core/middleware');

exports.handler = function (app) {
  const industry = ['Software Development', 'Construction', 'Financial Services']
  const function = ['SaaS', 'React', 'Sales']
  const service = ['executive', 'retained', 'contingent']
  const country = ['united states', 'australia', 'france']
  const state = ['california', 'new york', 'texas']
  const city = ['san francisco', 'san jose', 'san mateo']

  app.get('/:param1/:param2/', (req, res) => {
    if (industry.includes(req.params.param2)) {
      if (function.includes(req.params.param1))
        templateView('test', 'cars', {}, [])(req, res)
      else if (toys.includes(req.params.param1))
        templateView('test', 'toys', {}, [])(req, res)
      else
        res.send('This neither a car nor a toy');
    }
    else
      res.send('This is not a valid colour');
  });
}

Yes.

You can’t use bindings here. You need to hardcode everything. For this you qiuld need to require knex, add your db connection details or read them from the db.json file and run a knex where statement to get all records.

You need to cover all possible url structures including those parameters that could be optional.

Another option @mgaussie is an internal rewrite as suggested by @patrick. And I now believe it will the best option going forward. You could maintain all core routing functionality while providing disambiguation via a DB query and some conditions.

Patrick suggested in our example something like this which will rewrite the url internally but doesn’t redirect the end-users.

exports.handler = function(app) {
  const cars = ['ford', 'seat', 'toyota'];
  const toys = ['ball', 'frisbee', 'stick'];
  const colours = ['blue', 'red', 'green'];

  app.get('/:param1/:param2/', (req, res, next) => {
    if (colours.includes(req.params.param2)) {
      if (cars.includes(req.params.param1)) {
        req.url = '/car' + req.url;
      } else if (toys.includes(req.params.param1)) {
        req.url = '/toy' + req.url;
      }
    }
    next();
  });
}

You could create the urls via the routing panel and use something there like:

/recruiters/i/:industry/f/:function/c/:country/s/:state/c/:city/s/:service

Then in the middleware instead of calling the templateView function you just rewrite the url internally using a switch-case, if-elseif-else or even mapping with object literals or object spread(you can search for this).

It would look like something like this:
req.url = '/recruiters/i/'+req.params.param1+'/f/'+req.params.param2+...;

That way your users will keep using the old urls and they will still see in the browser address bar the same old URL as this is not a redirect but a rewrite. You also keep fully the usage of Wappler’s UI for routing and you make sure that future updates don’t mess up your implementation.

In Summary:

  1. You create the disambiguated routes in the routing panel in Wappler
  2. You use custom routing middleware
  3. You perform a query via knex in the middleware to see if the parameter is contained among those thousands of categories. You can read database connection details from your /app/modules/connections/db.json file
  4. You use conditionals to decide what url rewrite you need
  5. This rewrite matches one the disambiguated routes you create in step 1)

In your example, is it possible to fill the const cars with values from the database dynamically?