middle
Что такое Forge Storage API и Custom UI?
Forge Storage API — встроенное хранилище данных для Forge-приложений, позволяющее сохранять данные без собственной БД. Custom UI — возможность использовать полноценное React-приложение вместо декларативного UI Kit.
Типы хранилища
| Тип | Лимит | Назначение |
|---|---|---|
| Key-Value (storage) | 32 KB на ключ | Конфигурация, маленькие данные |
| Entity Storage | 32 KB на entity, queryable | Структурированные данные с поиском |
| Secrets | 4 KB | Токены, пароли |
Key-Value Storage
Пример
import { storage } from '@forge/api';
await storage.set('config:PROJ', { enabled: true, maxRetries: 3 });
const config = await storage.get('config:PROJ');
await storage.delete('config:PROJ');
// Список ключей (с пагинацией)
const result = await storage.query()
.where('key', startsWith('config:'))
.limit(20)
.getMany();
Entity Storage (структурированное хранилище)
Пример
// Сохранение entity
await storage.entity('task-record').set('task-001', {
projectKey: 'PROJ',
status: 'active',
score: 85,
createdAt: Date.now()
});
// Поиск по атрибутам
const activeTasks = await storage.entity('task-record')
.query()
.index('projectKey')
.where('projectKey', 'PROJ')
.sort('createdAt', 'DESC')
.limit(50)
.getMany();
Custom UI (React-приложение)
Пример
// static/my-custom-ui/src/App.tsx
import React, { useEffect, useState } from 'react';
import { invoke, view } from '@forge/bridge';
import Button from '@atlaskit/button';
const App: React.FC = () => {
const [details, setDetails] = useState(null);
useEffect(() => {
invoke('getIssueDetails').then(setDetails);
}, []);
return (
<div style={{ padding: '16px' }}>
<h3>{details?.summary}</h3>
<p>Статус: {details?.status}</p>
<Button appearance="primary" onClick={() => invoke('saveScore')}>
Сохранить
</Button>
</div>
);
};
Bridge API (@forge/bridge)
Пример
import { invoke, view, router } from '@forge/bridge';
const result = await invoke('functionName', { param1: 'value' });
const context = await view.getContext();
const issueKey = context.extension.issue.key;
await router.navigate('/browse/PROJ-123');
Частые ошибки
- Хранение большого объёма данных в Storage (>32KB) — ошибка при записи
- Не использовать Entity Storage для данных, по которым нужен поиск — Key-Value не поддерживает query
- Не собирать Custom UI перед forge deploy — забыть
npm run buildв static/ - Прямые вызовы Jira REST API из Custom UI (frontend) — нужно через resolver (backend)
Как используется в 2026
- Entity Storage стал основным способом хранения данных в Forge
- Custom UI + Atlaskit — стандарт для сложных UI
- Forge Remote Backend — позволяет вызывать внешние серверы из Forge
- Storage API получил улучшенные лимиты и возможности запросов
На собеседовании: разграничьте Key-Value (простое, без поиска) и Entity Storage (с индексами и query). Custom UI даёт полную свободу дизайна через React + Atlaskit, UI Kit проще для стандартных сценариев. Все вызовы API из Custom UI идут через resolver (backend), а не напрямую.