0.6.5 • Published 6 months ago

@vrabbi/plugin-tech-radar v0.6.5

Weekly downloads
-
License
Apache-2.0
Repository
github
Last release
6 months ago

@backstage/plugin-tech-radar

The Backstage integration for the Tech Radar based on Zalando's Tech Radar open sourced on GitHub. This is used at Spotify for visualizing the official guidelines of different areas of software development such as languages, frameworks, infrastructure and processes.

Read the blog post on backstage.io about the Tech Radar.

Purpose

Zalando has a fantastic description on their website:

The Tech Radar is a tool to inspire and support engineering teams at Zalando to pick the best technologies for new projects; it provides a platform to share knowledge and experience in technologies, to reflect on technology decisions and continuously evolve our technology landscape. Based on the pioneering work of ThoughtWorks, our Tech Radar sets out the changes in technologies that are interesting in software development — changes that we think our engineering teams should pay attention to and consider using in their projects.

It serves and scales well for teams and companies of all sizes that want to have alignment across dozens of technologies and visualize it in a simple way.

Getting Started

The Tech Radar can be used in two ways:

  • Simple (Recommended) - This gives you an out-of-the-box Tech Radar experience. It lives on the /tech-radar URL of your Backstage installation.
  • Advanced - This gives you the React UI component directly. It enables you to insert the Radar on your own layout or page for a more customized feel.

Install

For either simple or advanced installations, you'll need to add the dependency using Yarn:

# From your Backstage root directory
yarn add --cwd packages/app @backstage/plugin-tech-radar

Configuration

Modify your app routes to include the Router component exported from the tech radar, for example:

// In packages/app/src/App.tsx
import { TechRadarPage } from '@backstage/plugin-tech-radar';

const routes = (
  <FlatRoutes>
    {/* ...other routes */}
    <Route
      path="/tech-radar"
      element={<TechRadarPage width={1500} height={800} />}
    />

If you'd like to configure it more, see the TechRadarPageProps and TechRadarComponentProps types for options:

export type TechRadarPageProps = TechRadarComponentProps & {
  title?: string;
  subtitle?: string;
  pageTitle?: string;
};

export interface TechRadarPageProps {
  width: number;
  height: number;
  svgProps?: object;
}

Radar properties

When defining the radar entries you can see the available properties on the file api

Tech radar data model

NameTypeDescriptionRequired?
titlestringThe title of the radarYes
quadrantsquadrant[]The 4 quadrants of the radar, clockwise starting at the bottom rightYes
ringsring[]The radar rings, starting from the insideYes
entriesentry[]The radar entriesYes

quadrant

NameTypeDescriptionRequired?
idstringThe id of the quadrantYes
namestringThe name of the quadrantYes

ring

NameTypeDescriptionRequired?
idstringThe id of the ringYes
namestringThe name of the ringYes
colorstringThe color of the ring and entries inside the ringYes

entry

NameTypeDescriptionRequired?
idstringThe unique id from the entryYes
titlestringThe title that is shown in the radarYes
descriptionstringThe full description of the entryNo
keystringThe entry keyYes
urlstringThe URL to the entry internal or external pageNo
quadrantstringThe name of the quadrant connected to the entryYes
timelinetimeline[]Requires minimal one timeline entryYes

timeline

NameTypeDescriptionRequired?
movednumberPossible values are: -1 (moved out), 0 (stayed), 1 (moved in)Yes
ringIdstringThe ring idYes
datestringDate in format (YYYY-MM-dd)Yes
descriptionstringA long descriptionYes

Sample

This is a sample on how the JSON file could look like. The TS example can be found here.

{
    "title": "Title of your Tech radar",
    "quadrants": [
        {
            "id": "1",
            "name": "Bottom right"
        },
        {
            "id": "2",
            "name": "Bottom left"
        },
        {
            "id": "3",
            "name": "Top left"
        },
        {
            "id": "4",
            "name": "Top right"
        }
    ],
    "rings": [
        {
            "id": "adopt",
            "name": "ADOPT",
            "color": "#93c47d"
        },
        {
            "id": "trial",
            "name": "TRIAL",
            "color": "#93d2c2"
        },
        {
            "id": "assess",
            "name": "ASSESS",
            "color": "#fbdb84"
        },
        {
            "id": "hold",
            "name": "HOLD",
            "color": "#efafa9"
        }
    ],
    "entries": [
        {
            "id": "typescript",
            "title": "Typescript",
            "description": "Long description for Typescript",
            "key": "typescript",
            "url": "#",
            "quadrant": "1",
            "timeline": [
                {
                    "moved": 0,
                    "ringId": "trial",
                    "date": "2022-02-06",
                    "description": "Long description for trial"
                },
                {
                    "moved": 1,
                    "ringId": "adopt",
                    "date": "2022-02-08",
                    "description": "Long description for adopt"
                }
            ]
        },
        ...
    ]
}

Frequently Asked Questions

Who created the Tech Radar?

ThoughtWorks created the Tech Radar concept, and Zalando created the visualization that we use at Spotify and in this plugin.

How do I load in my own data?

The TechRadar plugin uses the techRadarApiRef to get a client which implements the TechRadarApi interface. The default sample one is located here. To load your own data, you'll need to provide a class that implements the TechRadarApi and override the techRadarApiRef in the app/src/apis.ts.

// app/src/lib/MyClient.ts
import {
  TechRadarApi,
  TechRadarLoaderResponse,
} from '@backstage/plugin-tech-radar';

export class MyOwnClient implements TechRadarApi {
  async load(id: string | undefined): Promise<TechRadarLoaderResponse> {
    // if needed id prop can be used to fetch the correct data

    const data = await fetch('https://mydata.json').then(res => res.json());

    // For example, this converts the timeline dates into date objects
    return {
      ...data,
      entries: data.entries.map(entry => ({
        ...entry,
        timeline: entry.timeline.map(timeline => ({
          ...timeline,
          date: new Date(timeline.date),
        })),
      })),
    };
  }
}

// app/src/apis.ts
import { MyOwnClient } from './lib/MyClient';
import { techRadarApiRef } from '@backstage/plugin-tech-radar';

export const apis: AnyApiFactory[] = [
  /*
  ...
  */
  createApiFactory(techRadarApiRef, new MyOwnClient()),
];

How do I write tests?

You can use the svgProps option to pass custom React props to the <svg> element we create for the Tech Radar. This complements well with the data-testid attribute and the @testing-library/react library we use in Backstage.

<TechRadarComponent
  width={1400}
  height={800}
  svgProps={{
    'data-testid': 'tech-radar-svg',
  }}
/>

// Then, in your tests...
// const { getByTestId } = render(...);
// expect(getByTestId('tech-radar-svg')).toBeInTheDocument();

How do I support multiple radars

The TechRadarPage and TechRadarComponent components both take an optional id prop which is subsequently passed to the load method of the API to distinguish which radar's data to load.