Skip to main content

Port SDK

The Port Backstage plugin is designed with flexibility in mind, allowing you to fully customize how data is presented in your Backstage instance. Since the Port SDK returns standard JavaScript objects, you have complete control over the presentation layer.

Port SDK

The 4 Pillars of the Port SDK

  1. Data model: Integrations are mapped (using JQ) to Blueprints, which are similar to tables in a database.
  2. Scorecards: Scorecards are JSON rules that are executed on the data model and return a score.
  3. Actions: Actions are JSON defined UI forms that execute your prebuilt workflows or call your internal APIs. supports REST API, Github actions, CircleCI and more.
  4. Automations: Automations are workflows (CI, REST API and more...) that are executed upon data model changes or time-based events.

Understanding the Data Structure

When you fetch data using the Port SDK, you receive plain JavaScript objects that you can manipulate and render however you prefer.

For example the following code fetches an entity from Port of type SERVICE_BLUEPRINT_ID with the identifier SERVICE_NAME:

// Example of data returned from Port SDK
const { data: entityData } = useEntityQuery(SERVICE_NAME, SERVICE_BLUEPRINT_ID);
The data structure returned from the Port SDK hook
const examplePortEntity: PortEntity = {
identifier: "backend-service-001",
title: "Backend Service API",
team: ["backend-team", "platform-team"],
icon: "api",
blueprint: "microservice-blueprint",
properties: {
language: "typescript",
version: "1.2.0",
deploymentRegion: "us-east-1",
isPublic: false,
},
relations: {
"depends-on": ["database-001", "cache-service"],
"maintained-by": "backend-team",
"monitored-by": null,
},
scorecards: {
"security-checks": {
rules: [
{
identifier: "dependency-scan",
status: "SUCCESS",
level: "critical",
ruleResults: [
{
result: true,
condition: {
property: "vulnerabilities",
operator: "=",
value: 0,
},
},
],
},
{
identifier: "authentication-check",
status: "FAILURE",
level: "high",
ruleResults: [
{
result: false,
condition: {
property: "auth-method",
operator: "contains",
value: "oauth2",
},
},
],
},
],
level: "critical",
},
"performance-checks": {
rules: [
{
identifier: "response-time",
status: "SUCCESS",
level: "medium",
ruleResults: [
{
result: true,
condition: {
property: "avg-response-time",
operator: "<",
value: 200,
},
},
],
},
],
level: "medium",
},
},
};

Creating Custom Components

You can create your own components to display Port data in ways that match your organization's needs:

import { useEntityQuery } from "@port-labs/backstage-plugin-framework";

const CustomEntityCard = () => {
const { data: entity, loading } = useEntityQuery("entity-id", "blueprint-id");

if (loading) return <LoadingComponent />;

return (
<YourCustomCard>
{/* Render entity data however you want */}
<Title>{entity.title}</Title>
<StatusBadge status={entity.properties.status} />
{/* Add your custom styling and components */}
</YourCustomCard>
);
};

Customization Examples

1. Custom Scorecard Visualization

Instead of using the default scorecard view, you can create your own visualization:

const CustomScorecard = () => {
const { scorecard } = usePortScorecard("scorecard-id");

return (
<CustomChart
score={scorecard.score}
rules={scorecard.rules}
// Add your custom styling and logic
/>
);
};

2. Custom Entity List

Create your own layout for displaying multiple entities:

const CustomEntityList = () => {
const { entities } = usePortEntities();

return (
<CustomGrid>
{entities.map((entity) => (
<CustomCard
key={entity.id}
title={entity.title}
metrics={entity.properties.metrics}
// Add your custom styling and components
/>
))}
</CustomGrid>
);
};

Integration with Existing Components

You can easily integrate Port data with your existing Backstage components:

import { Table } from "@backstage/core-components";

const PortDataTable = () => {
const { entities } = usePortEntities();

const columns = [
{ title: "Name", field: "title" },
{ title: "Owner", field: "properties.owner" },
// Add more columns as needed
];

return (
<Table
data={entities}
columns={columns}
// Use existing Backstage table features
/>
);
};

Best Practices

  1. Data Transformation

    • Create utility functions to transform Port data into your preferred format
    • Keep transformation logic separate from presentation components
  2. Component Reusability

    • Build reusable components that can handle different types of Port entities
    • Use TypeScript interfaces to ensure type safety
  3. Performance

    • Implement proper loading states
    • Consider pagination for large data sets
    • Use memoization when appropriate
  4. Error Handling

    • Add proper error boundaries
    • Provide meaningful feedback to users when data loading fails

Available Hooks

The Port frontend plugin provides several hooks to help you access and manipulate data: