How to generate openapi specification with nestjs without running the application - node.js

We have many APIs written in nodejs, using nestjs framework.
We can generate openapi.yaml using SwaggerModule from nestjs. that works perfectly. But the problem is that it needs the API to be up, and therefore that the database is up and running. That's a problem for us in our CI/CD, because we need to generate openapi specification before running the API.
Is it possible to generate openapi specification from our code, without needing to run the application?
Or maybe is there a simple way to mock our database?
Thanks for your help

The short answer is no, there isn't a way to generate the docs without running the NestJS application. However, you can generate a JSON file representing the OpenAPI documentation and then generate a static website from there. This issue gets you half-way there:
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const options = new DocumentBuilder()
.setTitle('Cats example')
.setDescription('The cats API description')
.setVersion('1.0')
.addTag('cats')
.build();
const document = SwaggerModule.createDocument(app, options);
const outputPath = path.resolve(process.cwd(), 'swagger.json');
writeFileSync(outputPath, JSON.stringify(document), { encoding: 'utf8'});
await app.close();
}
bootstrap();
This will generate a file swagger.json containing the OpenAPI specification. From there, you can use a tool like Spectacle to generate the actual HTML:
npx spectacle-docs -t public/docs swagger.json
An even less documented feature is the ability to retrieve a JSON representation of the OpenAPI specification from the regular endpoint using only curl.
Let's say you have a standard #nestjs/swagger integration that publishes the OpenAPI docs to /docs/:
const options = new DocumentBuilder()
.setTitle('core-api')
.setDescription('The core API description')
.setVersion('3.0')
.addTag('core-api')
.setBasePath(version)
.build();
const document = SwaggerModule.createDocument(app, options);
SwaggerModule.setup('docs', app, document);
If you browser to http:/localhost:3000/docs/, you can access the HTML version of the docs. However, if you browser to http://localhost:3000/docs-json you will receive a JSON representation. Simply append -json to whatever you spec path is.
Tying this all together, you can integrate this into a CI pipeline with a little hackery. I have integrated this into a Gitlab CI pipeline like so:
script:
- until nc -vz $API_IP 3000; do sleep 1; done
- curl http://$API_IP:3000/docs-json -o swagger.json
- npx spectacle-docs -t public/docs swagger.json
In your CI pipeline, you'll still have to run your NestJS application and as well as Mongo and any other dependant services required for it to start, but once you generate the JSON you can stop your application, build the static HTML site and publish it elsewhere.

I managed to generate the swagger spec from my e2e tests without starting the server
generating swagger json file without running nest js server

Related

What library can I use to generate random mock data based on Open API spec inside a node application?

I am looking for a library which would generate a mock data based on openapi spec (client side only). So the idea is not to have a separate local server, as it's done in openapi-mock-express-middleware, but rather have data to be generated on fly inside front-end application.
Something like this I guess:
const spec = someOpenApiMockGenerator('path/to/spec-file.yaml');
const anEndPointData = spec.mock("someEndpointName");
console.log(anEndPointData);
// expected output is same as in expressjs middlware mentioned above.

How to integrate swagger with restify framwork in node

I implemented a project for test purpose with restify framework in node and implemented a GET API.
But I don't know how to integrate a swagger with restify framework.
There are many blogs for integration swagger with express..
I followed a link like
https://www.npmjs.com/package/restify-swagger-jsdoc
https://github.com/bvanderlaan/swagger-ui-restify
Please help me how to integrate.
For everyone who's come this far, as well as me, I assume you're using restify instead of express and haven't found an easy answer yet. I have an API server using restify, use typescript to program and convert the files to javascript before running my server, all in a Docker container. After a lot of searching I managed to solve my problem as follows:
Install the "swagger-autogen" package.
Create a file called "swagger.ts" with the following commands:
const swaggerAutogen = require('swagger-autogen')()
const outputFile = '../swagger_output.json'
const endpointsFiles = ['../routes/users.router.ts'] // root file where the route starts.
swaggerAutogen(outputFile, endpointsFiles)
.then(() => {
require('./dist/src/app.js') // Your project's root file
})
Go to the files reserved for your API routes (where they have the GET, POST, PATCH, ... functions) -- in my case '../routes/users.router.ts', and put comments, like :
// #swagger.path = "/users"
// #swagger.tags = ['User']
// #swagger.description = 'Endpoint to create a user.'
/*
#swagger.responses[201] = {
schema: { "$ref": "#/definitions/User" },
description: "User was successfully created." }
*/
NOTE: To learn more about these swagger-autogen comment tags see:
https://github.com/davibaltar/swagger-autogen#swagger-20
Run the following command: (In my case, this command is in a script in package.json that is called inside the Dockerfile):
NOTE: Remember that if you don't automatically generate the javascript files from the script in typescript you need to create your structure entirely in javascript and not in typescript. Pay attention to file names and extensions.
node ./dist/src/server/swagger.js // change to your path
When you do this a swagger_output.json file will be created containing your application details.
After the file has been generated, you need to install the "swagger-ui-restify" package.
Put these commands where the middlewares are (usually at application startup):
const swaggerUi = require("swagger-ui-restify")
const swaggerDocument = require("../swagger_output.json")
const swaggerOptions = {
explorer: true,
baseURL: 'api-docs',
}
app.get("/api-docs"+'/*', ...swaggerUi.serve)
app.get("/api-docs", swaggerUi.setup(swaggerDocument, swaggerOptions))
Now your application has a middleware to consult the automatically generated documentation.

Generate Swagger Document for existing NodeJS server

According to Swagger website, there are two approaches: Bottom-up and Top-down.
I have an existing NodeJS server that I'd like to deploy in the Azure enviroment, that require a swagger document (API APP).
Does anyone know a tool for generating the swagger using the code? Even better if you could point a tutorial. I couldn't find it.
Question is a bit old but still. It is possible to generate completely automatically Swagger (OpenAPI) specification just by embedding analysis middleware like this: https://github.com/mpashkovskiy/express-oas-generator
const express = require('express');
const expressOasGenerator = require('express-oas-generator');
let app = express();
expressOasGenerator.init(app, {});
run some client or REST API tests agains your service and open http://host:port/api-docs
It’s not difficult to integrate Swagger in exist express applications following this tutorial.
Generally, we can follow these steps:
Add the dependencies in our package.json, and run npm install to install them. The dependencies should be:
"dependencies": {
"swagger-node-express": "~2.0",
"minimist": "*",
"body-parser": "1.9.x",
...
}
Download the zip project of Swagger-UI, copy the dist folder into the root directory of our project, the directory should almost like:
Introduce the dependencies at the beginnng of app.js:
var argv = require('minimist')(process.argv.slice(2));
var swagger = require("swagger-node-express");
var bodyParser = require( 'body-parser' );
Set up a subpath for swagger doc:
var subpath = express();
app.use(bodyParser());
app.use("/v1", subpath);
swagger.setAppHandler(subpath);
Make sure that /dist is able to serve static files in express:
app.use(express.static('dist'));
Set the info for API:
swagger.setApiInfo({
title: "example API",
description: "API to do something, manage something...",
termsOfServiceUrl: "",
contact: "yourname#something.com",
license: "",
licenseUrl: ""
});
Introduce /dist/index.html for swagger UI:
subpath.get('/', function (req, res) {
res.sendfile(__dirname + '/dist/index.html');
});
Complete the swagger configurations:
swagger.configureSwaggerPaths('', 'api-docs', '');
var domain = 'localhost';
if(argv.domain !== undefined)
domain = argv.domain;
else
console.log('No --domain=xxx specified, taking default hostname "localhost".');
var applicationUrl = 'http://' + domain;
swagger.configure(applicationUrl, '1.0.0');
Configure doc file dependence in /dist/index.html:
if (url && url.length > 1) {
url = decodeURIComponent(url[1]);
} else {
<del>url = "http://petstore.swagger.io/v2/swagger.json";</del>
url = "/api-docs.json";
}
Create api-docs.json file with the info of your APIs, put it in the dist folder.
Run the Express app on local, visit http://localhost:3000/v1, we can check the swagger doc.
Here is my test sample repo for your reference.
To my knowledge, your options are:
Using swagger-node-express which is very cumbersome in my opinion.
Writing up the swagger document manually yourself with the help of swagger editor as suggested in this SO Answer
If you go for option 2, you could use swagger-ui-express to generate the swagger-ui
A lot of developers are still having this problem so I built an open-source tool to help -- the tool is kind of like Git for APIs. It works by running a proxy while you're developing the API, analyzing the traffic, and updating the spec for you as the API's behavior changes. Hopefully, the workflow saves you a lot of time: https://github.com/opticdev/optic
Most alternatives require some sort of API specification through Json, Yaml or even embedded in JSdocs. On the other hand there are some runtime analyzers intercepting HTTP requests and building that specification on-demand.
express-sitemap-html follows a different approach inspecting the express object and its routes at setup time. Thus it always provides an up-to-date swagger UI for installed routes on existing express instance.
const sitemap = require('express-sitemap-html')
...
sitemap.swagger('Title', app) // app is an express instance
Then get swagger UI from your domain /api-docs.

Node.js Swagger generate UI doc JSON feed

I'm using Node.js and Swagger to build a restful API. The Swagger UI (demo link here http://petstore.swagger.io/) requires a JSON feed.
How would you generate this feed based on the Swagger spec yaml file? Is there not a npm module that can iterate over the yaml file and generate the JSON feed? I'm new to Swagger so I might have overlooked something.
Swagger UI should support YAML by now. You can convert YAML to JSON using JSYAML library.
You can also use the Swagger Editor:
http://editor.swagger.io/#/
I can't say I have tried it before, but you can upload YAML and export as YAML or JSON.
I have used the editor before and do really like it.
EDIT:
So to setup the swagger ui I did the following:
var swaggerUi = new SwaggerUi({
url:"http://petstore.swagger.io/v2/swagger.json",
dom_id:"swagger-ui-container"
});
swaggerUi.load();
That comes from here:
https://github.com/swagger-api/swagger-ui
I think you got that part.
As for the doc (YAML or JSON) just serve it out from your site. If you are using express with your nodejs server just serve out the file statically:
http://expressjs.com/starter/static-files.html
app.use('/static', express.static('public'));
So in this case if you put the swagger.json file right under your public dir you can access it with:
http://<yoursite>/swagger.json
Just test that you can actually get to your swagger docs from that url in the browser. Put that URL into the 'url' parameter above when you setup swagger-ui and you should be go to go. Swagger-ui will do the rest for you, it will pull the json or yaml definition from your site and generate the interactive docs site.

Building a simple RESTful API with Mongo and Node

So I'm working with a project that recently switched over to Node from Rails, where one of my favorite features was how easy it was to create a simple REST API, like so:
localhost:3000/materials/ Gets a JSON document of all objects
inside materials
localhost:3000/materials/:id Gets a JSON output of the object with
that id, e.g. /materials/123123 gives me item 123123
localhost:3000/materials/ Gets a JSON document of all objects
inside materials
And so on. I'm using Mongo. Is there a way of doing this in Node, or is there a guide or a package I should install that can do this?
Check out LoopBack from StrongLoop Suite, it has a built-in RESTful api explorer that interacts with Mongo using the mongodb connector. http://docs.strongloop.com/loopback/#using-the-api-explorer and http://strongloop.com/strongloop-suite/loopback/
For example, you could create the "materials" model with just the following commands:
slc lb model materials and then the restful api will get auto-generated for you at localhost:3000/explorer.
You can use Restify, to build RESTful Web Services in Node.js
A good tutorial at: https://www.openshift.com/blogs/day-27-restify-build-correct-rest-web-services-in-nodejs
Express seems like what you want. You can specify routes very simply as follows:
app.get('/:collection', function(request, response) {
// the value of :collection is stored in request.params
var coll = request.params.collection;
var search = request.query; // a hash containing the querystring arguments
// do stuff with request body, query parameters, etc.
response.send(data); // send the response
});
app.get('/:collection/:item', function(request, response) {
var coll = request.params.collection;
var item = request.params.item;
// do stuff
res.json(data); // can also send a JSON response
});
Take a look at restgoose. It is a Typescript library that makes simple REST API development super simple.
https://xurei.github.io/restgoose/

Resources