How to integrate swagger with restify framwork in node - node.js

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.

Related

What is the best way to handle CAS authentication in NodeJS accross multiple route files?

I am working on an inventory management system RESTful API in NodeJS right now. The API will be accessed by a standalone VueJS application through HTTP requests. I want to use CAS to prevent access to API resources to unauthenticated users. I have settled on using the library found here: https://www.npmjs.com/package/node-cas-authentication
I have got the library working for CAS authentication, but I have to duplicate the initializing code across all of my route files.
The initializing code I have to keep repeating:
const CASAuth = require('node-cas-authentication');
const cas = new CASAuth({
cas_url : 'https://my-cas-host.com/cas',
service_url : 'https://my-service-host.com',
is_dev_mode : true
});
My file structure:
I wanted to know if there is a better way to organize my code so that I do not have to continuously repeat the initializing code in each file. If there is so way to include the CAS Authentication via a separate file and I require, this would be beneficial for organization and for maintenance. I am fairly new to NodeJS, so any suggestions would be helpful!
One option is to create a new module, say cas-middleware.js, which performs the initialization and exports the resulting object:
// cas-middleware.js
const CASAuth = require('node-cas-authentication');
const cas = new CASAuth({
cas_url : 'https://my-cas-host.com/cas',
service_url : 'https://my-service-host.com',
is_dev_mode : true
});
module.exports = cas; // Add this line
You can then reference that same object from all of your other modules using require:
// e.g., routes.js
const cas = require('../cas-middleware')
Each module that imports the object from cas-middleware.js will receive a reference to the same CASAuth object.

How to generate openapi specification with nestjs without running the application

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

Location of Mirage files in ember addon

I have an Ember addon which is supposed to handle a request to return some data. The main app needs to use this addon, so that requests to retrieve this data are retrieved from mirage. At some point in the future this needs to be disabled in live environments (but not for the time being)
My question is where the mirage directory (and its subdirectories such as factories, fixtures, models, routes etc) should be located in an addon. Should it be in the project root or elsewhere, such as in the app or addon subdirectory?
I have run:
ember install ember-cli-mirage
which creates some files in \tests\dummy\mirage
Creating the files in this directory doesn't seem to work:
/tests/dummy/fixtures/mydata.js
export default [{
"title": "Some data here"
}]
/tests/dummy/routes/mydata.js
class MyDataRoutes {
constructor(routerFnc, route, db) {
routerFnc(route + '/', ({db}) => {
return db.mydata;
});
}
}
export default MyDataRoutes;
/tests/mirage/config.js:
export default function() {
// this.urlPrefix = ''; // make this `http://localhost:8080`, for example, if your API is on a different server
this.namespace = 'api'; // make this `api`, for example, if your API is namespaced
this.timing = 100; // delay for each request, automatically set to 0 during testing
new MyDataRoutes(this.get, '/content/mydata', this.db);
}
This is the right place.
You will then be able to use your mirage endpoints either in your tests or in the dummy app directly.
If you want an example of how that would all work together, you can have a look at the repo for ember-power-select https://github.com/cibernox/ember-power-select. They have mirage as well as nice tests in place.

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.

Add express middleware for param validations

In a sails.js application is there a simple way of including express-middleware?
For instance extending the request object with express-validator.
Adding express-middleware in a sails application is simple.
create a new policy.
policies
|_
middleware.js / .coffee
Add Express MiddlewareYOUR_MIDDLE_WARE_FILE_NAME.js
Inside your middleware file we create the standard export for node.js
module.exports = require('middle-ware')(OPTIONS_GO_HERE) // See middleware docs for configuration settings.
Then once you have created the middleware you can apply it to all requests or a single controller by following the Sails.js convension.
Entire Applicationpolicies.js
module.exports.policies = {
'*':['middleware'] // node same name as file without extention
}
Single Controller Action policies.js
module.exports.policies = {
RabbitController:{
feed:['middleware']
}
}
First of all, #SkyTecLabs' answer is the proper way to do this. But I wanted to add that, in some cases, you may need to control your static files (images, client-side javascript, css, etc) as well (I just had to deal with this recently). In this case, you can apply middleware generically to every route.
As of Sails.js v0.9.3, you can do:
// Put this in `config/express.js`
module.exports.express = {
customMiddleware: function (app) {
app.use(require('../node_modules/sails/node_modules/express').basicAuth('balderdash', 'wickywocky'));
}
};
More here: https://gist.github.com/mikermcneil/6255295
In the case where you want middleware to run before one or more of your controllers or actions, you're definitely better served using the policy approach though!

Resources