Does NestJS support middleware with gRPC? I'm following the example project here and then the middleware for logging the request entrypoint here.
In the example project it looks like there is an Express server along with the gRPC server. I'm using just a gRPC server.
const app = await NestFactory.createMicroservice<MicroserviceOptions>(...);
await app.listenAsync();
So adding the following to the main app module:
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggerMiddleware)
.forRoutes('*');
}
}
But nothing is logging.
Middleware is exclusive to HTTP handlers. If you need middleware-like functionality, it would be better to use one of Nest's enhancers (guards, interceptors, pipes, or filters). If you're looking to do some logging I'd suggest an intereptor as you have pre- and post- controller logic.
There's also my logging library Ogma which has a Nest package and interceptor already which might be useful to look at
Related
I'm making an API using NestJS (NodeJS) and in order to run it in local enviromment without having all external APIs running, i want to mock the calls to external APIs while my API running.
In order to do this, I choose Json-server to do it, Here is the code:
mockserver.ts:
export async function bootstrap() {
const app = create();
app.use(
defaults({
logger: true,
static: 'static',
}),
router(dbJSON),
jsonServer.rewriter(routesJSON),
);
app.use('/api', router);
}
i tried also :
export async function bootstrap() {
const app = create();
app.use(
defaults({
logger: true,
static: 'static',
}),
router(db),
jsonServer.rewriter(routesJSON),
);
app.use('/api', router);
const port = process.env.mockPort ?? 8080;
app.listen(port);
main.ts :
async function bootstrap() {
const app = await NestFactory.create(AppModule)
const mocks = await import('../mocks/server');
app.use(await mocks.bootstrap(null));
await app.listen(DEFAULT_HTTP_PORT, DEFAULT_HOST);
}
However, instead of mocking the calls to external APIs using the db and the routes given to Json-server, my API itself was mocked.
Any ideas on how can I mock an API calls to external API while running? or how to make json-server mock call httpService calls only instead of the API itself
I haven't tried this before, but I think you either need to configure the existing HttpModule to sometimes forward calls or wrap HttpModule with a new module that decides whether or not to forward requests to the real server or mock server.
You can give HttpModule a configuration via register. See the async configuration if you want to inject ConfigService to configure it based off of an environment variable that determines if you're local or not. The config object is an Axios request config. However, I don't see a way to redirect requests via config.
HttpModule uses axios, so another option would be axios interceptors. In a request interceptor, you could have it only override config.url when running locally. To set up interceptors at the beginning of the app, you could create a module MyHttpModule that injects HttpService, and in an onModuleInit, get a reference to the axios instance and set the interceptors. Check out this example I found.
In Fastify I can specify instance options while creating it, e.g.
const fastify = require('fastify')({logger:true, disableRequestLogging: false});
Is it possible to do this in a middleware registered with the instance?
e.g. if I do something like
fastify.register(myPlugin);
and instance of fastify is passed to myPlugin - can I, for example change its disableRequestLogging value while in the middleware?
The router is the what relies on disableRequestLogging to switch on/off logging for the request and the later response.
if (disableRequestLogging === false) {
childLogger.info({ req: request }, 'incoming request')
}
The router does provide a setup function that allows disableRequestLogging to be changed. You can see fastify.js uses router.setup() late in initialisation here to apply some new values.
The problem is fastify doesn't provide access to router as part of it's public API. Only functions like fastify.get/.post/.route etc which allow access to specific components of the router.
Short of modifying the source, I can't see a way. Not even something dodgey like onkeypatching a function in due to the way fastify variables are scoped. Even if you could do that, it would be delving into undefined/untested behaviours.
Fastify has its own package to handle strategies, which is fastify-auth. Among its strategies include fastify-basic-auth and fastify-jwt.
NestJS has a wrapper for passport strategies; #nestjs/passport, along with its documentation. I don't think they have a wrapper for Fastify strategies. I'm not sure how I would go about implementing the strategies into the project.
In the end, I would like to do the following:
#UseGuards(AuthGuard('FastifyBasicAuth'))
#Post('login')
async login() {
/* Logic... */
}
I would like to build an application and its recommended to use GraphQl for API,
I am not sure which platform to select and what are the differences.
apollo server vs express-graphql
I need to use TypeScript for the project too.
Any good Idea would be appreciated.
Below is the now deleted section from the apollo-server README comparing apollo-server to express-graphql.
Note that some of these arguments do not apply anymore e.g. express-grapqhl is now written in TypeScript. Hence the removal of this section from the README.
One observation is that apollo-server is too bloated, and is slowly showing a lack of maintenance. I would go with express-graphql instead if I were to pick one today. But this is personal preference and you should do your own due diligence.
There's also a community-maintained Koa port of express-graphql, called koa-graphql. Using either express-graphql, or koa-graphql, combined with something like envelop, you can achieve everything, if not more, the Apollo "ecosystem" provides in a more modular manner.
Comparison with express-graphql
Both Apollo Server and
express-graphql are
GraphQL servers for Node.js, built on top of the graphql-js
reference implementation, but
there are a few key differences:
express-graphql works with Express and Connect, Apollo Server supports Express, Connect, Hapi, Koa and Restify.
Compared to express-graphql, Apollo Server has a simpler interface and supports exactly one way of passing queries.
Apollo Server separates serving GraphiQL (an in-browser IDE for
exploring GraphQL) from responding to GraphQL requests.
express-graphql contains code for parsing HTTP request bodies, Apollo Server leaves that to standard packages like body-parser.
Apollo Server includes an OperationStore to easily manage whitelisting.
Apollo Server is built with TypeScript.
application/graphql requests
express-graphql supports the application/graphql Content-Type for
requests, which is an alternative to application/json request with
only the query part sent as text. In the same way that we use
bodyParser.json to parse application/json requests for
apollo-server, we can use bodyParser.text plus one extra step in
order to also parse application/graphql requests. Here's an example
for Express:
'body-parser'; import { graphqlExpress } from 'apollo-server-express';
const myGraphQLSchema = // ... define or import your schema here!
const helperMiddleware = [
bodyParser.json(),
bodyParser.text({ type: 'application/graphql' }),
(req, res, next) => {
if (req.is('application/graphql')) {
req.body = { query: req.body };
}
next();
} ];
express()
.use('/graphql', ...helperMiddleware, graphqlExpress({ schema: myGraphQLSchema }))
.listen(3000); ```
Express-GraphQL is a piece of middleware, to quickly setup a GraphQL Server, either with Express, or any web-framework that supports middleware.
Apollo-server is a package that will sit on an existing node server and parse the GraphQL queries. (Very similar to express-graphql) You can use it with express, Koa etc.
My recommendation is use Graphql-yoga as it's built with apollo-server and express-graphql. And it's built and maintained by the Prisma Team.
I suggest using apollo-server-express over express-graphql. They are very similar, but apollo-server-express has more bells and whistles all while having a simpler and clearer API IMO.
The biggest improvement in apollo-server-express, for me, is the playground: https://github.com/prisma/graphql-playground
The playground is better than express-graphql's graphiql for several reasons, but one big one is that it allows you to put HTTP headers in the request, which is more appropriate for handling session.
www.graphqlbin.com will allow you to use the playground on any endpoint which does not have cors. If you have cors, then you will need to run playground directly from your server.
Here is a sample of code to get you started:
const { ApolloServer } = require('apollo-server-express')
const graphqlServer = new ApolloServer({
schema,
introspection: true,
playground: true,
})
graphqlServer.applyMiddleware({
app
})
I set globally middleware to attach data to request object and it work in http...
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer): void {
consumer.apply(AuthMiddleware).forRoutes('*');
}
But it is not work in gateway(websocket)...
why this middleware that set on all routes not work in gateway(websocket)...?
or
what is the best way for attach authorized user to request in http and websocket...?
You've got the answer from creator of the framework. Just in case someone is facing the same
Middleware don't apply to the websockets - it's not an issue. Use interceptor/guard instead.
https://github.com/nestjs/nest/issues/1634#issuecomment-472553863