WebSequenceDiagrams.com TypeScript Client
https://gist.github.com/rclayton-the-terrible/493cd0811542ff9693ac02746517ba71
TL;DR - TypeScript Client Gist: https://gist.github.com/rclayton-the-terrible/493cd0811542ff9693ac02746517ba71
If you are not familiar with WebSequenceDiagrams, it's an excellent tool for creating sequence diagrams for planning software flows. If you are not familiar with sequence diagrams, a quick Google search will provide many great blogs on what they are and how they are created. We use them at Peachjar to plan distributed microservices flows (they are universally loved by our engineers because of their utility).
Example of a sequence diagram
Despite the utility of sequence diagrams, trying to generate them using a GUI diagramming tool is a pain in the butt. While there are some special-purpose tools that make the process easier, many developers prefer to use a declarative markup language to build them because they can be easily updated and versioned source control. WebSequenceDiagrams makes this possible for sequence diagrams by converting a text-based sequence diagram specification into an image.
The following code renders the sequence diagram (above):
title WebSequenceDiagrams Client
Caller->+Client: Generate Diagram
Client->+WebSequenceDiagrams: Create Diagram
alt no api key and using paid features
WebSequenceDiagrams-->Client: 402 - You need to pay
Client-->Caller: <YouNeedToPayWSDSome$$$Error>
end alt
WebSequenceDiagrams-->-Client: 200 - <Errors, Link to Diagram>
alt has errors
Client-->Caller: <InvalidSequenceDiagramError>
end alt
Client->+WebSequenceDiagrams: Get image
WebSequenceDiagrams-->-Client: <Image>
Client-->-Caller: <Image>
For this reason, I'm building a tool at work that automatically generates these diagrams when files are changed (allowing them to be embedded in Github Markdown), as well as, creating a pipeline in CircleCI that will regenerate the images when changes are checked in.
This endeavor involves a lot of glue code to watch for file changes and call the appropriate services to generate diagrams on change. One of our needs (obviously) is to call the WebSequenceDiagrams API to convert our text-based sequence specifications into PNG images.
There are existing WebSequenceDiagram clients in various languages, even one for Node.js hildjj/node-websequencediagrams. However, I wanted a client in TypeScript and the existing Node client doesn't have support for supplying an API Key (allowing the use of paid-features).
There is a pull request for adding the API Key (https://github.com/hildjj/node-websequencediagrams/pull/9), but it seems to be languishing on a branch for some reason (no updates since March).
So I went ahead and created a client in TypeScript, though I'm providing it as a Gist and not an NPM package (it's super simple, only depends on Axios - so please just copy the code into your project) because I don't want to manage issues and pull requests (sorry, I'm busy).
WebSequence Diagram TypeScript Client
https://gist.github.com/rclayton-the-terrible/493cd0811542ff9693ac02746517ba71
The Gist includes:
WebSequenceDiagramClient.ts
- the actual client codeWebSequenceDiagramClient.integ.ts
- integration testsWebSequenceDiagramClient.js
- the compiled clientjest.integ.config.js
- the Jest configuration for running the integration testsLICENSE.md
- MIT license; do what you wish but don't sue me.
Using the client is pretty simple:
import Axios from 'axios'
import WebSequenceDiagramClient, { Styles, ImageTypes } from './WebSequenceDiagramClient'
// I force you to create the Axios client, mostly for unit testing reasons.
// I inject this using Awilix to better control my object graph (which is why it's
// currently done this way with)
const axios = Axios.create({ baseURL: 'http://www.websequencediagrams.com' })
const client = new WebSequenceDiagramClient(axios)
const diagram = `
title Hello
A->B: text
`
// Image will be a buffer
const image = await client.generateDiagram(Buffer.from(diagram))
// You can customize the client as well:
const customizeClient = new WebSequenceDiagramClient(axios, {
style: Styles.modernblue,
imageType: ImageTypes.pdf,
apiKey: process.env.WEBSEQUENCEDIAGRAMS_API_KEY,
})
PDF and SVG image types are paid-features and require an apiKey
!
Room for improvement
Of course, there are some areas of the client that can be improved, but I'm not motivated at the moment to implement this:
- Validate that
apiKey
is supplied ifimageType
ispdf
orsvg
- Have the client create the Axios client if not supplied (using a default value).
Oh yeah, the tests pass
Without the API Key:
# ./node_modules/.bin/jest --config jest.integ.config.js
npm run test:integ
With the API Key:
# ./node_modules/.bin/jest --config jest.integ.config.js
WEBSEQUENCEDIAGRAMS_API_KEY=<key> npm run test:integ
You might also be interested in these articles...
Stumbling my way through the great wastelands of enterprise software development.