UNPKG

protobuf2swagger

Version:

Convert protobuf to swagger open api v2, v3 JSON

181 lines (156 loc) 4.91 kB
# protobuf2swagger Work in progress project for saving some life, update not garrenteed. Welcome for pull request :). Main purpose is to convert [protobuf v2](https://developers.google.com/protocol-buffers/docs/proto) file to [openapi v3](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md) JSON schema with NodeJS, and merge with some custom open api configurations. Then you may render it easily with [SwaggerUI](https://github.com/swagger-api/swagger-ui). # What is supported - customSchema in OAS v2 or v3 formats - convert _service_ to paths - convert _enum_, _enum_ to schemas in components/definitions, paths will reference to them - basic types mapping to JS type _number_, _string_, _boolean_ ( long types will be mapped to _string_) - **nested**, **repeated** types # Install `npm i -g protobuf2swagger` # Cli Usage `protobuf2swagger [config_file]` | Argument | Description | | ----------- | --------------------------------------------------------------------------------------------- | | config_file | Customize configuration file. Default to **protobuf2swagger.config.js** under current folder. | For options may check `protobuf2swagger --help`. (Nothing there yet, seriously.) ## Config File Example: ```javascript module.exports = { // ERQU files: ['test1.proto', 'test2.proto'], // Optional dist: 'apischema.json', // Optional formatServicePath: (path) => path.replace(/\./g, '/'), // Optional, will convert long to string by default long: 'number', // Optional // This will merge and overwrite the result parsed from protobuffer file. // `paths` will merge by path // `components` will merge by component except shcemas customSchema: { swagger: '2.0', paths: { '/api/test': { get: { responses: { 200: { schema: { $ref: 'GetDataResponse', // Tell me the protobuf message name }, }, }, params: [], }, }, }, components: { securitySchemes: { cookieAuth: { type: 'apiKey', in: 'cookie', name: 'token', }, }, }, security: [ { cookieAuth: [], }, ], }, // Optional, you may use this hook to overwrite the original transform result. transform(type, result, args) { switch (type) { case 'field': { const [field, options] = args; console.log('message field:', field); console.log('options:', options); break; } case 'message': { const [message, options] = args; console.log('message:', messsage); console.log('options:', options); break; } case 'enum': { const [enum] = args; console.log('enum:', enum); break; } case 'service': { const [service, root, options] = args; console.log('service:', service); console.log('proto root:', root); console.log('options:', options); } } return result; }, }; ``` # Display with SwaggerUI index.html (modified from swagger-ui-dist) ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>API Document</title> <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.22.2/swagger-ui.css" /> <style> html { box-sizing: border-box; overflow: -moz-scrollbars-vertical; overflow-y: scroll; } *, *:before, *:after { box-sizing: inherit; } body { margin: 0; background: #fafafa; } </style> </head> <body> <div id="swagger-ui"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.22.2/swagger-ui-bundle.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.22.2/swagger-ui-standalone-preset.js"></script> <script> window.onload = function () { // Begin Swagger UI call region const ui = SwaggerUIBundle({ url: './apischema.json', // Path to the generated schema JSON file dom_id: '#swagger-ui', deepLinking: true, presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset], plugins: [SwaggerUIBundle.plugins.DownloadUrl], layout: 'StandaloneLayout', }); // End Swagger UI call region window.ui = ui; }; </script> </body> </html> ``` Serve with simple [express](https://www.npmjs.com/package/express) server: ```javascript const express = require('express'); const app = express(); app.use(express.static(__dirname /* path to index.html */)); app.listen(3000); console.info('Served at port 3000'); ```