asyncapi / asyncapi/cli

[TEST] : low coverage in lib/apps/api/middlewares

Open
#2,019 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
272
Forks
375
Avg merge
3h 22m
Merged PRs (30d)
8

Description

Current API middleware implementations have very low test coverage and contain tightly coupled logic that makes testing, debugging, and maintenance difficult. In particular, validation and error handling paths include complex async flows, repeated schema compilation, and limited observability during request processing.

Image

### Proposed Changes
1. **Validator Caching** (Performance Improvement)
Avoid recompiling AJV validators for every request.
```
class ValidatorCache {
private cache = new Map();

async getValidator(path, method) {
const key = `${path}:${method}`;
if (!this.cache.has(key)) {
this.cache.set(key, await this.compileValidator(path, method));
}
return this.cache.get(key);
}
}
```
2. **Simplified Validation Middleware Flow** :
```
async function validationMiddleware(options) {
return async (req, res, next) => {
try {
sanitizeInput(req.body);

const validate =
await validatorCache.getValidator(options.path, options.method);

if (!validate(req.body)) {
throw new ProblemException({ status: 422 });
}

await validateDocuments(req, options);

next();
} catch (err) {
next(err);
}
};
}
```
3. **Problem Middleware Error Handling**

**Helper utilities**
```
function extractErrorType(type: string): string {
return type.replace('https://api.asyncapi.com/problem/', '');
}

function categorizeError(status: number): 'client' | 'server' {
return status >= 500 ? 'server' : 'client';
}
```
So the simplified middleware flow:
```
function problemMiddleware(error, req, res, next) {
if (res.headersSent) {
return next(error);
}

try {
const problemShape = error.get();
const status = problemShape.status || 500;
problemShape.status = status;
problemShape.title ||= 'Internal server error';

const errorType = extractErrorType(problemShape.type);
const category = categorizeError(status);

logger.error(
`[${req.method}] ${req.path} >> Status:: ${status}, Type:: ${errorType}`,
{ category }
);

const problem = error.toObject({
includeStack: status >= 500,
includeCause: status >= 500,
});

res.status(status).json(problem);
} catch (err) {
next(err);
}
}
```
### Steps to Reproduce:
- `npx nyc npm test`
- `npx nyc report --reporter=html`
- `start coverage/index.html`
- Navigate to `problem.middleware.js`, `validation.middleware.js`

Happy to raise a PR for this if the maintainers approve

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.