If you’re using Meshery or if you like the project, please ★ this repository to show your support! 🤩
Meshery follows schema-driven development. As a project, Meshery has different types of schemas. Some schemas are external facing, and some internal to Meshery itself. This repository serves as a central location for storing schemas from which all Meshery components can take reference.
Meshery schemas offer a powerful system designed for:
- Model-Driven Management: Meshery uses explicit models for describing infrastructure and applications.
- Dynamic Discovery: The ability to process different kinds of relationships and styles, enables a sophisticated system that can adapt to many configurations.
- Lifecycle Management: The schema properties track status and lifecycle of resources.
- Extensibility: Open-ended metadata and modular schema components enable expansion and customization.
- Visual Representation: The properties for styling of edges and nodes is for creating a user friendly visual representation.
- Automated Operations: The schemas can support validation and automated configuration of infrastructure and applications, and patching.
For an explanation of Meshery's terminology regarding schemas, definitions, declarations, and instances, please see Contributor's Guide to Models.
--> For an explanation of the directory structure of this repository and how to contribute changes to Meshery's schemas, see Contributor's Guide to Schema-Driven Development.
Our projects are community-built and welcome collaboration. 👍 Be sure to see the Contributor Welcome Guide and Community Handbook for a tour of resources available to you. Jump into community Slack or discussion forum to participate.
MeshMates are experienced community members, who will help you learn your way around, discover live projects, and expand your community network. Connect with a Meshmate today!
Find out more on the Meshery community.
✔️ Join any or all of the weekly meetings on community calendar.
✔️ Watch community meeting recordings.
✔️ Fill-in a community member form to gain access to community resources.
✔️ Discuss in the Community Forum.
✔️ Explore more in the Community Handbook.
Not sure where to start? Grab an open issue with the help-wanted label.
Please do! We're a warm and welcoming community of open source contributors. All types of contributions are welcome. Please read:
- General Contributor Guide - Overview of contribution processes
- Schema Contributor Guide - Schema-specific development workflows and guidelines
Meshery follows a Schema-Driven Development (SDD) approach. This means that the structure of data used throughout the system is centrally defined using schemas. These schemas power consistency, validation, and code generation across the Meshery platform.
Meshery uses the OpenAPI v3 specification to define and manage schemas. Given the complexity of the platform, Meshery adopts a modular, versioned, and extensible schema strategy:
- ✅ Versioned schemas for backward compatibility.
- 🧩 Modular constructs for maintainability and reuse.
- 🧪 Schemas are used for validation, API documentation, and automatic code generation.
💡 TIP: When referencing models or other constructs in the schema, always add
x-go-typeandx-go-import-pathto avoid generating redundant Go structs. Refer to existing patterns in the codebase.
All schemas are located in the schemas/ directory at the root of the Meshery repository:
schemas/
constructs/
<schema-version>/ # e.g., v1beta1
<construct>/ # e.g., model, component
api.yml # Index file: references all subschemas + defines API endpoints
<construct>.yaml # Subschema: data model definition for the construct
<other_subschema>.yaml # Additional subschemas (optional)
templates/ # Manually defined templates directory
<construct>_template.json # JSON template from schema
<construct>_template.yaml # YAML template from schema
<variant>_template.json # Additional variant templates (optional)
typescript/ # TypeScript source and generated files
index.ts # Manually maintained - public API surface
generated/ # Auto-generated (do NOT commit)
<schema-version>/
<construct>/
<Construct>.d.ts # TypeScript type definitions
<Construct>Schema.ts # OpenAPI schema as JS object
rtk/ # RTK Query client configurations
cloud.ts
meshery.ts
dist/ # Built distribution (do NOT commit)
index.js, index.d.ts
cloudApi.js, mesheryApi.js
constructs/ # Built schema exports (renamed from 'generated')
<schema-version>/<construct>/<Construct>Schema.js
models/ # Auto-generated Go code (do NOT commit)
<schema-version>/
<construct>/
<construct>.go
constructs/– Holds schemas for various versions.<schema-version>/– Represents a version (e.g.,v1alpha2,v1beta1).<construct>/– A directory to contain all files for any given construct likepattern,component, etc.api.yml– The index file for the construct. This file:- References all subschemas (via
$ref) to bundle them together - Defines all API endpoints (REST operations: GET, POST, PUT, DELETE) for the construct
- Serves as the entry point for code generation tools (oapi-codegen, openapi-typescript)
- References all subschemas (via
<construct>.yaml– A subschema that defines the data model (noun) for the construct. Contains the schema properties, types, and validation rules.- Other
.yamlfiles – Additional subschemas can be defined in separate files (e.g.,model_core.yml,component_metadata.yml) and referenced fromapi.yml. templates/– A subdirectory containing manually defined template files. You can add as many different templates here for different variants, use cases, or configurations. Templates are example instances of the schema with default or sample values.<construct>_template.json/<construct>_template.yaml– Default templates in JSON/YAML format.- Additional variant templates can be added (e.g.,
<construct>_minimal_template.json,<construct>_full_template.yaml) for different use cases.
-
Property names
- Use camelCase for property fields (e.g.,
schemaVersion,displayName,componentsCount). - Identifier fields use lowerCamelCase with "Id" suffix (e.g.,
modelId,registrantId,categoryId). - Enums use lowercase words (e.g.,
enabled,ignored,duplicate).
- Use camelCase for property fields (e.g.,
-
OpenAPI schema names
- PascalCase nouns under
components/schemas(e.g.,Model,Component). - Files/folders are lowercase:
api.yml(index),<construct>.yaml(subschemas),templates/<construct>_template.(json|yaml).
- PascalCase nouns under
-
Endpoints and operations
- Paths are under
/apiwith kebab-case , plural nouns (e.g.,/api/workspaces,/api/environments). - Path params are camelCase (e.g.,
{subscriptionId},{connectionId}). - Non-CRUD actions append a verb segment (e.g.,
.../register,.../export,.../cancel); legacy lowerCamelCase may appear (e.g.,.../upgradePreview). operationIdis camelCase VerbNoun (e.g.,registerMeshmodels).
- Paths are under
-
Versioning
schemaVersionuses group/version (e.g.,models.meshery.io/v1beta1,components.meshery.io/v1beta1).- Version strings follow k8s-style (
v1,v1alpha1,v1beta1); semver fields use standard SemVer.
Meshery supports automated code generation from schemas for:
- Go: Strongly-typed models for backend →
models/<version>/<package>/ - TypeScript Types: Interfaces and type definitions →
typescript/generated/<version>/<package>/<Package>.d.ts - TypeScript Schemas: OpenAPI schemas as const JS objects →
typescript/generated/<version>/<package>/<Package>Schema.ts - RTK Query: Clients generated from OpenAPI for use with Redux →
typescript/rtk/ - JSON/YAML: Templates with defaults and resolved references.
Each construct's OpenAPI schema is exported as a const JavaScript object for runtime use:
// Import from main index
import {
ModelDefinitionV1Beta1OpenApiSchema,
ComponentDefinitionV1Beta1OpenApiSchema,
DesignDefinitionV1Beta1OpenApiSchema,
} from "@meshery/schemas";
// Or import individual schemas directly
import ModelSchema from "@meshery/schemas/dist/constructs/v1beta1/model/ModelSchema";
import ComponentSchema from "@meshery/schemas/dist/constructs/v1beta1/component/ComponentSchema";Types are organized by version in namespaces:
import { v1beta1, v1alpha1 } from "@meshery/schemas";
const component: v1beta1.Component = { /* ... */ };
const model: v1beta1.Model = { /* ... */ };
const design: v1beta1.Design = { /* ... */ };Use the following command to perform the entire schema-driven generation workflow:
make build
npm run build # Build TypeScript distribution with tsup-
Bundles OpenAPI schemas for:
- Meshery
- Remote Providers (e.g. Meshery Cloud)
- Combined (all constructs)
-
Generates:
- Golang structs →
models/ - TypeScript type definitions (
.d.ts) →typescript/generated/ - TypeScript schema exports (
*Schema.ts) →typescript/generated/ - RTK Query clients →
typescript/rtk/
- Golang structs →
-
After
npm run build:- Builds distribution files →
dist/ - Creates CJS and ESM bundles
- Generates declaration files
- Builds distribution files →
⚠️ This is the recommended way to stay in sync with schema changes.
After running make build, three bundled schema files are created:
| File | Purpose |
|---|---|
merged_schema.yml |
All schemas combined (used by Meshery clients) |
cloud_schema.yml |
Cloud-specific APIs for Remote Providers (e.g. Meshery Cloud) |
meshery_schema.yml |
Meshery-specific APIs |
To control which schema paths are included in each bundled output, use the x-internal annotation inside the OpenAPI operations (get, post, etc.).
paths:
/api/entitlement/plans:
get:
x-internal: ["cloud"]
operationId: getPlans
tags:
- Plans
summary: Get all plans supported by the system
responses:
"200":
description: Plans fetched successfully
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Plan"- With
x-internal: Included only in the respective client (e.g.,cloud). - Without
x-internal: Included in all clients.
Meshery uses a helper script (generate.sh) to map schema constructs to generated output:
generate_schema_models <construct> <schema-version> [<openapi-file>]
generate_schema_models "capability" "v1alpha1"
generate_schema_models "category" "v1beta1"
generate_schema_models "pattern" "v1beta1" "schemas/constructs/v1beta1/design/api.yml"This maps to Go packages like:
models/v1alpha1/capability/capability.go
The OpenAPI bundle is passed to a codegen tool to generate RTK Query clients. Include relevant paths using x-internal annotations and define request/response schemas appropriately.
You can control this in generate.sh like:
# Merge relevant constructs for RTK generation
npx @redocly/cli join schemas/base_cloud.yml \
"${v1beta1}/pattern/${merged_construct}" \
"${v1beta1}/component/${merged_construct}" \
"${v1beta1}/model/${merged_construct}" \
... \
-o _openapi_build/merged_openapi.yml \
--prefix-tags-with-info-prop title \
--prefix-components-with-info-prop titleBefore using the generated RTK clients, ensure you have:
-
Installed the required dependencies:
@reduxjs/toolkit@meshery/schemas
-
Set up environment variables:
RTK_CLOUD_ENDPOINT_PREFIX: Base URL for Cloud API endpointsRTK_MESHERY_ENDPOINT_PREFIX: Base URL for Meshery API endpoints
To avoid cyclical imports that can break your application, import API slices from their specific exports:
// ✅ Correct: Import from specific API exports
import { cloudApi as cloudBaseApi } from "@meshery/schemas/dist/cloudApi";
import { mesheryApi } from "@meshery/schemas/dist/mesheryApi";
// ❌ Incorrect: Do not import directly from generic API file
// import { api } from "@meshery/schemas/dist/api"; // Can cause cyclical importsAdd the API reducers and middleware to your Redux store configuration:
import { combineReducers, configureStore } from "@reduxjs/toolkit";
import { cloudApi as cloudBaseApi } from "@meshery/schemas/dist/cloudApi";
import catalogReducer from "./slices/catalog";
import connectionReducer from "./slices/connection";
import organizationReducer from "./slices/organization";
import chartReducer from "./slices/charts";
import themeReducer from "./slices/theme";
// Optional: If you have locally defined APIs
import { cloudApi } from "../api";
// Combine reducers
const rootReducer = combineReducers({
catalog: catalogReducer,
charts: chartReducer,
organization: organizationReducer,
connection: connectionReducer,
theme: themeReducer,
// Add generated API reducers
[cloudBaseApi.reducerPath]: cloudBaseApi.reducer,
// Optional: Add locally defined API reducers
[cloudApi.reducerPath]: cloudApi.reducer
});
// Configure store with middleware
export const store = configureStore({
reducer: reduxPersist.createPersistEnhancedReducer(rootReducer),
middleware: getDefaultMiddleware =>
getDefaultMiddleware()
// Add generated API middleware
.concat(cloudBaseApi.middleware)
// Optional: Add locally defined API middleware
.concat(cloudApi.middleware)
// Add persistence middleware if needed
.concat(reduxPersist.persistMiddleware)
});
// Set up listeners for RTK Query cache behaviors like refetchOnFocus/refetchOnReconnect
setupListeners(store.dispatch);After configuring your store, you can import and use the generated hooks:
import {
useGetPlansQuery,
useCreateDesignMutation,
useGetDesignsQuery,
// Other cloud API hooks...
} from "@meshery/schemas/dist/cloudApi";
function MyComponent() {
// Use hooks directly in your components
const { data: plans, isLoading, error } = useGetPlansQuery();
// Handle loading states
if (isLoading) return <div>Loading plans...</div>;
// Handle errors
if (error) return <div>Error loading plans</div>;
// Use data
return (
<div>
{plans.map(plan => (
<div key={plan.id}>{plan.name}</div>
))}
</div>
);
}import {
useGetMeshModelsQuery,
useSubmitMeshConfigMutation,
// Other Meshery API hooks...
} from "@meshery/schemas/dist/mesheryApi";
function MesheryComponent() {
const { data: meshModels } = useGetMeshModelsQuery();
// ...
}-
Stuck Loading States:
- Verify environment variables are correctly set
- Check for CORS issues
- Ensure proper authentication headers are included
-
Cyclical Imports:
- Always import from specific API files (
cloudApi.ts,mesheryApi.ts) - Avoid importing from generic
api.tsfiles
- Always import from specific API files (
-
Multiple RTK Instances:
- Ensure proper reducer and middleware registration
- Check for naming conflicts in reducerPaths
For better debugging, use Redux DevTools to monitor:
- API request lifecycles
- State changes
- Caching behavior
-
Handle Loading States:
const { data, isLoading, isFetching, error } = useGetDataQuery();
-
Leverage Cache Options:
const { data } = useGetDataQuery(null, { pollingInterval: 30000, // Re-fetch every 30 seconds refetchOnMountOrArgChange: true, skip: !isReady // Skip query when not ready });
-
Use Transformations When Needed:
const transformedData = data?.map(item => ({ ...item, formattedValue: formatValue(item.value) }));
Validate your schema updates before committing by running:
make buildOr validate a single file:
npx @redocly/cli lint schemas/constructs/v1beta1/pattern/api.yml| Task | Command |
|---|---|
| Generate everything | make build |
| Build TypeScript dist | npm run build |
| Generate Go code only | make golang-generate |
| Generate TS types + schemas | make generate-ts |
| Lint OpenAPI | npx @redocly/cli lint |
// Via namespaces (types)
import { v1beta1 } from "@meshery/schemas";
const model: v1beta1.Model = { /* ... */ };
// Via schema exports (runtime)
import { ModelDefinitionV1Beta1OpenApiSchema } from "@meshery/schemas";
// Direct schema import
import ModelSchema from "@meshery/schemas/dist/constructs/v1beta1/model/ModelSchema";This repository and site are available as open-source under the terms of the Apache 2.0 License.
MESHERY IS A CLOUD NATIVE COMPUTING FOUNDATION PROJECT
