From e5c1134eab7459d998b671973592c537767ea016 Mon Sep 17 00:00:00 2001 From: Vladimir Svacko Date: Wed, 28 Jan 2026 16:10:49 +0100 Subject: [PATCH] fix: arch diagram --- README.md | 88 ++++++++++++++++++++++++++++++++++++++++++ docs/arch-diagram.png | Bin 0 -> 20036 bytes docs/arch-diagram.svg | 1 + 3 files changed, 89 insertions(+) create mode 100644 docs/arch-diagram.png create mode 100644 docs/arch-diagram.svg diff --git a/README.md b/README.md index 14e8a3e..b3ecb57 100644 --- a/README.md +++ b/README.md @@ -543,6 +543,94 @@ Based on the Zabbix configuration above, the API will return: 4. Push to the branch (`git push origin feature/amazing-feature`) 5. Open a Pull Request +## 🏗️ Architecture + +The Zabbix GraphQL API follows a layered architecture pattern with clear separation of concerns: + +![Architecture Diagram](docs/arch-diagram.svg) + +
+ +```PlantUML +@startuml +title Zabbix GraphQL API - Simplified Data Flow + +[GraphQL Client] as client +[Apollo Server\n(Entry Point)] as server +[Schema Loader\nDynamic Merging] as schema +[Resolvers\nHierarchical] as resolvers +[Data Sources\nZabbix API Wrappers] as datasources +[Zabbix Server] as zabbix +[Execution Layer\nBusiness Logic] as execution + +client -> server : "Query/Mutation" +server -> schema : "Resolve Schema" +schema -> resolvers : "Route to Resolver" +resolvers -> datasources : "Fetch Data" +datasources -> zabbix : "API Call" +zabbix -> datasources : "Response" +datasources -> resolvers : "Process" +resolvers -> server : "Format" +server -> client : "Result" + +resolvers --> execution : "Complex Operations" +execution --> datasources : "Use DataSources" +@enduml +``` +
+ +### Core Components + +- **Entry Point**: `src/index.ts` → `src/api/start.ts` (Apollo Server setup) +- **Schema Loading**: `src/api/schema.ts` - Dynamic schema merging with extensibility via environment variables +- **Resolvers**: `src/api/resolvers.ts` + dynamic hierarchical resolvers via `resolver_helpers.ts` +- **DataSources**: `src/datasources/` - Zabbix API wrappers extending `RESTDataSource` +- **Execution**: `src/execution/` - Complex business logic (importers, deleters) + +### Data Flow + +1. **Client Request**: GraphQL queries/mutations arrive at the Apollo Server +2. **Schema Resolution**: Schema loader merges base schema with additional schemas (if configured) +3. **Resolver Execution**: Resolvers handle the request, using data sources to communicate with Zabbix +4. **Zabbix Communication**: Data sources make API calls to the Zabbix server +5. **Response Processing**: Results are processed and returned to the client + + +### DataSources Structure + +The `src/datasources/` directory contains specialized Zabbix API wrappers: + +- `zabbix-api.ts`: Main Zabbix API class extending `RESTDataSource`, handles authentication and communication +- `zabbix-{entity}.ts`: Specialized request classes for specific Zabbix entities (e.g., hosts, templates, etc.) +- Each DataSource follows the pattern of extending `ZabbixRequest` for type-safe API calls + +### Key Architectural Patterns + +#### 1. Hierarchical Data Mapping +Automatic mapping of Zabbix items/tags to GraphQL nested objects: +- Zabbix item key `state.current.values.temperature` → GraphQL `{ state: { current: { values: { temperature } } } }` +- Implemented via `createHierarchicalValueFieldResolver()` in `resolver_helpers.ts` +- Type hints: `json_`, `str_`, `bool_`, `float_` prefixes for value conversion + +#### 2. Dynamic Schema Extension (No-Code) +Configure via environment variables: +```bash +ADDITIONAL_SCHEMAS=./schema/extensions/display_devices.graphql,./schema/extensions/location_tracker_devices.graphql +ADDITIONAL_RESOLVERS=SinglePanelDevice,FourPanelDevice,DistanceTrackerDevice +``` + +#### 3. Mass Import/Export Pattern +All importers follow hierarchy-first approach: +- **Host Groups**: Process parent groups before children (`getHostGroupHierarchyNames()`) +- **Template Dependencies**: Handle dependent items via deferred creation logic +- **Batch Processing**: Each importer returns array of `Response` objects with success/error details + +#### 4. Permission System +Uses Zabbix template groups as permission containers: +- Template groups with prefix `Permissions/` (configurable via `ZABBIX_PERMISSION_TEMPLATE_GROUP_NAME_PREFIX`) +- Queries: `hasPermissions()`, `userPermissions()` in resolvers +- Integration: `ZabbixRequestWithPermissions` wrapper class + ## 📄 License This project is licensed under the AGPL-3.0 License - see the [LICENSE](LICENSE) file for details. diff --git a/docs/arch-diagram.png b/docs/arch-diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..66bca4b971874807e97c4ea7d2717d365e1f91f4 GIT binary patch literal 20036 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 >dQ)<~x9vD5Y$ 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

9zur{ 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 Zc$iyc)gv!T0wdNabhQm{muo%>`w#Di(t7{^ literal 0 HcmV?d00001 diff --git a/docs/arch-diagram.svg b/docs/arch-diagram.svg new file mode 100644 index 0000000..e53b0e1 --- /dev/null +++ b/docs/arch-diagram.svg @@ -0,0 +1 @@ +Zabbix GraphQL API - Simplified Data FlowZabbix GraphQL API - Simplified Data FlowGraphQL ClientApollo Server(Entry Point)Schema LoaderDynamic MergingResolversHierarchicalData SourcesZabbix API WrappersZabbix ServerExecution LayerBusiness LogicQuery/MutationResultResolve SchemaRoute to ResolverFetch DataProcessAPI CallResponseFormatComplex OperationsUse DataSources \ No newline at end of file