Attach user details to request object in nestjs - nestjs

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

Related

What are the ways to expose GraphQL Schema as REST api?

I have Graphql api developed and want to expose few REST API endpoints from it. so here my intention is use same Graphql logic to expose it as rest api. So far I got posts about using sofa to achieve this and want to check if there is any NestJS or Graphql existing package which we can use.
It depends on how you've structured your application thus far. In general, NestJS promotes an N-tier architecture where business logic belongs inside of Services/Providers. When structured this way, it becomes relatively straightforward to share logic between GraphQL resolvers and HTTP controllers.
Resolvers and Controllers should act purely as routing components that receive requests/data and pass them to the appropriate service for processing.
#Resolver()
class MyResolver {
constructor(private readonly service: MyService) { }
#Query()
doSomething() {
return this.service.doSomething();
}
}
#Controller()
class MyController {
constructor(private readonly service: MyService) { }
#Get()
doSomething() {
return this.service.doSomething();
}
}
You have developed a GraphQL API , which you then want to expose as REST , or you want to integrate a REST API in your GraphQL API? If it's the first one , you are totally missing the point of GraphQL. If it's the second one , then you need to pass the context argument in your Apollo Server constructor , containing a dataSource argument. Then you have to define a class that extends RESTDataSource (https://www.apollographql.com/docs/apollo-server/data/data-sources/).

NestJS gRPC Middlware

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

Change server option in middleware

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.

Generate Open API Spec from Model/Controller Metadata in Loopback4

Does Loopback4 provide a way to generate an Open Api Spec from decorated models and controllers?
If not, is there a way to access controllers and models metadata at runtime?
Noticed just now that the server object exposes the getApiSpec method which returns an OpenApiSpec object.
export class MyController {
constructor(
#inject('application.instance') private app: Application,
#inject('rest.http.request') private req: ServerRequest) { }
#get('/spec')
async api(): Promise<OpenApiSpec> {
const server = await this.app.getServer(RestServer);
return server.getApiSpec();
}
}
EDIT: This solution doesn't solve the problem completely
The api spec returned by server.getApiSpec() doesn't contain information about the models.
After you started the LoopBack 4 application (assuming you did not change the REST server port), go to http://localhost:3000/openapi.json, you'll get the OpenAPI spec.

Using mobx-model in the server

I am using Mobx and mobx-model for state management in my React app. I am not doing server-side render as of now. But, I have a scenario where I need to use my model in the server side.
An example model in my project is shown below.
import { API, BaseModel } from "mobx-model";
class UserModel extends BaseModel {
...
static loadAll() {
...
}
}
The above model works fine in the client (in the browser). But, I have a scenario where I need to call the loadAll method from the server.
If I require this model from the server side as follows, I get an error.
const { UserModel } = require("../../src/models/models");
The error message is:
SyntaxError: Unexpected token import
Any idea how I can fix this to work on the server side?
I found a solution to this problem. Instead of requiring the UserModel, I could require the API from mobx-model as follows:
const { API } = require("mobx-model");
I could use the API from the server without much code changes. I have to rewrite a little bit of loadAll logic again in the server. That works for me for now.

Resources