Hilzu / express-openapi-validate

Express middleware to validate requests based on an OpenAPI 3 document
Apache License 2.0
75 stars 12 forks source link

Automatically find correct validator for an endpoint #10

Closed Hilzu closed 4 years ago

Hilzu commented 6 years ago

Using the req.route it should be possible to find the correct validator without the API consumer needing to pass in the method and path explicitly. This would make creating the validation middleware less verbose and remove the need to repeat the method and path in the validate call.

The bad side is that we can detect a missing validator only when the endpoint gets its first call and not when the endpoint is defined like with the explicit API. The cost of creating validators is also moved to call-time from application startup which might be a good or bad thing (application starts faster but the first calls to validated endpoints are a bit slower).

Even with these downsides it might be worth it to add an API like this.

// Something like this
app.post("/echo", validator.find(), (req, res, next) => {
  res.json({ output: req.body.input });
});

// instead of this (but keep this as a fallback)
app.post("/echo", validator.validate("post", "/echo"), (req, res, next) => {
  res.json({ output: req.body.input });
});
codeclown commented 6 years ago

Doesn't necessarily have to move the validation to when the endpoint is called, if using path-to-regex which is what express is using to match paths to routes.

Something like this should work (just example/pseudo code):

// When Validator is initialized, create regexes for the paths
const pathRegexes = Object.keys(schema.paths)
  .map(path => ({ path, regex: pathToRegex(path) }));

// Then the middleware
const magic = (req, res, next) => {
  const foundPath = pathRegexes.find(({ regex }) => regex.test(req.path));
  if (foundPath) {
    return validateWithSchema(schema.paths[foundPath.path]);
  }
  next();
};

// Later, before routes
app.use(validator.magic);