Creating a PDF Template for AsyncAPI Specifications Using React

Creating a PDF Template for AsyncAPI Specifications Using React

AsyncAPI is an open-source specification for describing asynchronous APIs. Creating a template for AsyncAPI involves defining the structure and content of your asynchronous API.

Understand the AsyncAPI Specification

Before creating a template for Generator tool, we need to know the specification required for AsyncAPI. Read the official documentation for understanding the key components, Such as

To understand the basics refer the Official documentation of AsyncAPI.

But for a simple overview one can also refer My blog.

Choose a Template Format

AsyncAPI supports Two templating formats:

  • YAML (YAML Aint’s Markup Language)

  • JSON (JavaScript Object Notation)

For this time, We shall use YAML extension.

Define the Template Structure

Before we create our YAML ( we can also say YML) we need to follow the following file/ directory structure,

my-template
├─ asyncapi.yml
├─ package.json
└─ src
├─ components
│  └─ PdfTemplate.js
├─ App.js
└─ index.js

Once this file structure is duplicated, We can follow up with creating the package.json file first.

Package.json

In the package.json file, specify the template engine, render and other configuration options we need.

For this template we are using react rendering engine.

{
  "name": "asyncapi-pdf-template",
  "version": "1.0.0",
  "description": "A PDF template generator for AsyncAPI specifications",
  "main": "index.js",
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "dependencies": {
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-scripts": "4.0.3",
    "asyncapi-react": "^1.0.0",
    "pdf-lib": "^1.17.1"
  },
  "devDependencies": {
    "eslint": "^7.32.0",
    "eslint-plugin-react": "^7.27.1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

Creating an AsyncAPI document :

In the asyncapi.yml file, we define our event-driven API using the AsyncAPI specification. This file will serve as the input for the template generation process.

asyncapi: '2.0.0'
info:
  title: My AsyncAPI PDF Template
  version: '1.0.0'
  description: A template for generating PDFs from AsyncAPI specifications.
servers:
  production:
    url: 'api.example.com'
    protocol: 'wss'
channels:
  myChannel:
    description: A channel for sending messages.
    subscribe:
      operationId: receiveMessage
      summary: Receive a message
      message:
        contentType: application/json
        payload:
          type: object
          properties:
            message:
              type: string

Creating PDF template component:

In the src/components/PdfTemplate.js file, create a react component that will render the PDF template. This component has to import the FILE component from @asyncapi/generator-react-sdk and use it to define the PDF file structure.


import React, { useState, useEffect } from 'react';
import { PDFDocument, rgb } from 'pdf-lib';
import PdfContent from './PdfContent';
import ReactDOMServer from 'react-dom/server';

const PdfTemplate = () => {
  const [pdfBytes, setPdfBytes] = useState(null);
  const [asyncapiData, setAsyncapiData] = useState({
    title: 'My AsyncAPI PDF Template',
    description: 'A template for generating PDFs from AsyncAPI specifications.',
    channels: [
      { name: 'myChannel', description: 'A channel for sending messages.' },

    ],
  });

  const generatePdf = async () => {
    const pdfDoc = await PDFDocument.create();
    const page = pdfDoc.addPage([600, 400]);

    // Render the PDF content using the PdfContent component
    const content = (
      <PdfContent
        title={asyncapiData.title}
        description={asyncapiData.description}
        channels={asyncapiData.channels}
      />
    );

    // Convert the React component to a string
    const contentString = ReactDOMServer.renderToStaticMarkup(content);


    page.drawText(contentString, {
      x: 50,
      y: 350,
      size: 12,
      color: rgb(0, 0, 0),
    });

    const pdfBytes = await pdfDoc.save();
    setPdfBytes(pdfBytes);
  };

  return (
    <div>
      <button onClick={generatePdf}>Generate PDF</button>
      {pdfBytes && (
        <a href={`data:application/pdf;base64,${pdfBytes}`} download="asyncapi.pdf">
          Download PDF
        </a>
      )}
    </div>
  );
};

export default PdfTemplate;

Create the main application component:

In the src/App.js file, create a React component that will render the main application. This component should import the ‘PdfTemplate’ components and use it to generate the PDF template

import React from 'react';
import PdfTemplate from './components/PdfTemplate';

function App() {
  return (
    <div className="App">
      <h1>AsyncAPI PDF Template</h1>
      <PdfTemplate />
    </div>
  );
}

export default App;

Create the index component:

In the src/index.js file, create a React component that will serve as the entry point for the template generation process. This componetns should import the ‘App’ component and use it to render the main application.

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

Installation of dependencies

After creating all the necessary javascript files and document , for running the Generator tool, we need to install the necessary dependencies in the my-template directory. we can do that by following commands.

npm install
npm install -g @asyncapi/cli

For running the Generator tool you can run the following command

#this command is the example
#asyncapi generate fromTemplate [path of your yml document] @asyncapi/[your template name] -o [path to store output]

For The file structure mentioned above the following commands suitable.

asyncapi generate fromTemplate asyncapi.yaml @asyncapi/pdf-template

Development guide

If you want to use my code for generator tool, the following steps will guide you easily with running the code base on your local machine.

  1. Fork and Clone the repository

First fork the repository from github and then clone it.

<https://github.com/{your_username}/Generator-Templates>
cd Generator-Templates

For using the python-mqtt-client-template

cd python-mqtt-client-template/
npm install
cd test/project/
python3 -m venv myenv
source myenv/bin/activate
pip install package_names
asyncapi generate fromTemplate asyncapi.yaml @asyncapi/python-paho-template

For running any other template from Generator-Templates .

Move to the directory of the template and run the following commands

npm install
npm install -g @asyncapi/cli
asyncapi generate fromTemplate asyncapi.yaml @asyncapi/pdf-template