What are the ways to expose GraphQL Schema as REST api? - node.js

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/).

Related

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

Attach user details to request object in 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

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.

Explain the service.js in AngularJS

I'm quite new to AngularJS and NodeJS. I'm trying to develop an app using MEAN stack. I just looked through the sample code in the mean.io boilerplate. I created my own app referring the sample app. I'm trying to submit the AngularJS front end and expecting it to call NodeJs server side but it isn't working. I think service.js is messing up something. Here is the service code of sample app. Can any one explain what this code does with respect to Angular client side and NodeJS Server side.
'use strict';
//Articles service used for articles REST endpoint
angular.module('mean.articles').factory('Articles', ['$resource', function($resource) {
return $resource('articles/:articleId', {
articleId: '#_id'
}, {
update: {
method: 'PUT'
}
});
}]);
It creates a new factory in angular called Articles. The Articles factory has the $resource service injected. The $resource object is used to setup an object for communicating with a RESTful service, in this case "articles/:articleId" the articleId will be pulled from the _id of the resource objects that are returned from queries using this $resource. When you call to update on one of the resources it will use the PUT HTTP Verb.
By itself this just defines the factory but doesn't actually make any calls you would need to inject this and use it somewhere like Articles.query();
From the docs
If the parameter value is prefixed with # then the value of that
parameter is extracted from the data object (useful for non-GET
operations).

Resources