How to call nestjs microservice from any frontend app? - javascript

I have a made a NestJS microservice package and separate NestJS client application for contacting the microservice. Below given is the code used in the client application. In microservice the method used is #messagePattern and it is functional. My question is how a front-end app can contact directly to the microservice without going through the client also how to setup swagger in microservice or test it directly from a postman ?
import { BadRequestException, Injectable, UnauthorizedException } from '#nestjs/common';
import { ClientProxy, ClientProxyFactory, Transport } from '#nestjs/microservices';
import { errorResponse, goodResponse } from 'src/helpers/response.helper';
import { AddContractDTO } from './contract.dto';
#Injectable()
export class ContractService {
private client: ClientProxy;
constructor() {
this.client = ClientProxyFactory.create({
transport: Transport.TCP,
options: {
host: '127.0.0.1',
port: 3011,
},
});
}
public async addContract(data: AddContractDTO) {
const res = await this.client.send<any,any>('contract/addContract', data).toPromise();
console.log(res);
if(!res.success){
throw new BadRequestException(res)
}
return goodResponse(res.data.data,'Contract created');
}
}

You cannot call the service directly. You need to create a controller (to bind to an endpoint) which then can call the service.
Examples can be found in the NestJS Documentation (https://docs.nestjs.com/microservices/basics).

Related

Asynchronous Axios Initiation

I am trying to initiate an Axios Client for my React app. I want to use the authenticated client to make requests. The current setup looks as followed. Due to the session service being async to check for a cached token and validating it against the server the initiation of the API Client is also async. This results in the client in the ExampleService being undefined when constructed too early.
The goal is to keep the Services as self contained as possible.
class ApiClientService {
client: AxiosInstance
async init() { // gets called asap on launch
await sessionService.init()
this.client = axios.create({
baseURL: config.host,
timeout: 1000,
headers: { Authorization: `token ${sessionService.getToken()}` }
})
}
getClient() {
return this.client
}
...
}
class ExampleService {
private client = apiService.getClient()
async doSomething() {
return this.client.get('/something')
}
}

How to import a Typescript or Javascript file from an external link?

I want to use some of the Deno standard libraries in Node.js to create an HTTP server.
I know that I can just download it but I want to stay updated with the latest library so I want to import them like this:
import { serve } from "https://deno.land/std/http/server.ts";
// Defining port to be used
const PORT = 8080
// Setting server to listen at port
const server = serve({ port: PORT });
console.log(`This Hello World server is up and running on http://localhost:${PORT}/`);
// Sending Hello World to any client that connects
for await (const req of server) {
req.respond({ body: "Hello World!\n" });
}
It's theoretically possible to use a limited subset of the Deno std library in Node (modules which use nothing from the web APIs, nothing from the Deno API, and include no import statements with specifiers ending in .ts).
However, the module from your example at https://deno.land/std/http/server.ts does not meet this criteria and will create both compile-time errors in tsc (TypeScript) and runtime errors in Node.js.
Nevermind I just want to use ES6+ syntax to create a server so I use this:
import https from "https";
import http from "http";
export default class Server {
readonly server: http.Server | https.Server;
constructor(options?: http.ServerOptions | https.ServerOptions, httpsMode?: boolean) {
this.server = (httpsMode ? https : http).createServer(options);
}
listen(port?: number, hostname?: string, backlog?: number) {
let s = this.server;
s.listen(port, hostname, backlog);
return {
[Symbol.asyncIterator]() {
return {
async next() {
return {
done: false,
value: await new Promise<{request: http.IncomingMessage, response: http.ServerResponse}>(result => {
s.on('request', (request, response) =>
result({request, response})
);
})
};
}
}
}
}
}
close() {
this.server.close();
}
}
This module is available on NPM, package Newer.js after I publish 0.0.4

NestJS HTTPS empty #POST() body

Im using NestJS via HTTPS.
import { NestFactory } from '#nestjs/core';
import { fstat } from 'fs';
import { AppModule } from './app.module';
import {readFileSync} from 'fs'
async function bootstrap() {
const httpsOptions = {
key:readFileSync('tsl/private-key.pem'),
cert:readFileSync('tsl/public-cert.pem')
}
const app = await NestFactory.create(AppModule,{httpsOptions});
await app.listen(3000);
}
bootstrap();
I try to get simple POST request:
#Post()
test(#Body() body){
console.log(body);
}
But output is always {}
POSTMAN:
I readed that nestjs cant parse data correctly. How can i fix that?
Your postman request needs to be set to raw and JSON, not raw and Text
Integrate swagger into your application.
It is an open API and supported by nestjs.
https://docs.nestjs.com/openapi/introduction

Initializing a class in a function vs in a class

So I am working in a project, which uses Nest.js
I have a custom package, which exports the configured redis object.
What I need to do, is initialize the custom redis class in a function, but all cases in our code, show how to do it in a class. Like so:
import { RedisService } from 'custom-redis-package';
//...
export class Gateway implements /*...*/ {
constructor(
private readonly redisService: RedisService,
) {
//...
}
public foo() {
this.redisService.bar()//... Use the redisService freely here.
}
}
The problem is now I need to initialize this redis package in a function in main.ts to use redis as session memory.
import { AppModule } from './app.module';
import { RedisService } from 'custom-redis-package';
import * as session from 'express-session';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const redis = new RedisService(); // This would work, but it want's the entire config object. So password, user, all the urls and so on, and it seems like a DRY violation
app.use(
session({
secret: 'secret',
resave: false,
saveUninitialized: false,
store: redis.getSessionStorage(session),//Unable to, RedisService is not initialized
}),
);
await app.listen(3000);
}
bootstrap();
So, how can I initialize RedisService without the whole config mess in a function?
Turns out there is smth like:
app.get(serviceAsImportedModule).
More info here:
https://docs.nestjs.com/standalone-applications#getting-started

express.session undefined in typescript

I am very new to typescript/javascript, I am trying to build backend rest apis with session
following is app.ts file
import express from "express";
import { applyMiddleware, applyRoutes } from "./utils";
import routes from "./services";
const app = express();
var ses= {
secret: "secret_session",
resave: true,
saveUninitialized: true,
cookie: { maxAge: 3600000,secure: false, httpOnly: true
}
if (app.get('env') === 'production') {
app.set('trust proxy', 1)
ses.cookie.secure = true
}
app.use(session(ses));
applyRoutes(routes, app);
I have started the server and applied the middlewares for error handling but those are not related to question in my opinion so I'm not adding code for it. Following is my routes.ts code where I'm trying to set the session.
import { Request, Response } from "express";
import { getAll, getByKeyword, addNewProduct } from "./productControllers";
{
path: "/api/v1/getAllProducts",
method: "get",
handler: [
(req: Request, res: Response) => {
getAll()
.then((row: any) => {
var sess = req.session;
sess.views = 1;
res.status(200).json({ data: row });
})
.catch(err => {
res.json({
message: err
});
});
}
]
}
I'm getting error at sess.views = 1;
I have tried the suggested questions before asking it, none of them were of any help to me.
EDIT:
I have created an index.ts
import searchRoutes from "./products/routes";
export default [...searchRoutes];
I have another util class
export const applyRoutes = (routes: Route[], router: Router) => {
for (const route of routes) {
const { method, path, handler } = route;
(router as any)[method](path, handler);
}
}
You are using an interface which is Request for express.js. But it doesn't have type definition for session. So typescript throws a compile error. To solve it you need to define session type under Request interface.
You could define a session.d.ts file under your project. And create required types & interfaces. Like:
declare global {
namespace Express {
interface Request {
session?: Session;
sessionID?: string;
}
}
}
interface Session{
mySessionVarible:string
}
But the good thing is we have DefinitilyTyped project which you can find many type definitions. This needs to solve your compile problem.
npm install --save-dev #types/express-session
And don't forget to change your import for Request.
import { Request, Response } from "#types/express-session";

Categories

Resources