Skip to content

Commit ee40abc

Browse files
committed
Update schema driven development docs
Signed-off-by: mermerlin320 <mrmerlin320@gmail.com>
1 parent 565a126 commit ee40abc

File tree

1 file changed

+78
-177
lines changed

1 file changed

+78
-177
lines changed

docs/pages/project/contributing/contributing-schemas.md

Lines changed: 78 additions & 177 deletions
Original file line numberDiff line numberDiff line change
@@ -27,212 +27,113 @@ go install github.com/deepmap/oapi-codegen/cmd/oapi-codegen@latest
2727

2828
### Development Workflow
2929

30-
#### Schema Resolution Process
31-
When you work with the schemas, you'll frequently use this essential command:
3230

33-
```bash
34-
make resolve-ref path="./schemas/constructs/[version]"
35-
```
31+
#### **Schema Definition in Meshery**
32+
Meshery uses **OpenAPI v3** specification to define schemas. Given the complexity of the project, where multiple constructs and APIs exist, we adopt a structured approach to schema management:
33+
- **Schemas are versioned** to maintain backward compatibility.
34+
- **Schemas are modular** to support different components of Meshery independently.
35+
- **Schemas are used for validation, API definition, and automatic code generation.**
3636

37-
**Key functions:**
38-
1. Resolves `$ref` references between schema files
39-
2. Adds code generation metadata tags
40-
3. Creates complete, self-contained schemas
41-
4. Validates reference consistency
42-
43-
**Example:**
44-
Consider this schema snippet with an external reference:
45-
46-
```json
47-
"capabilities": {
48-
"type": "array",
49-
"description": "Meshery manages components...",
50-
"items": {
51-
"$ref": "../v1alpha1/capability.json" // reference here
52-
}
53-
}
54-
```
37+
### **Schema Directory Structure**
38+
All schemas are stored in the **`schemas`** directory at the root of the project. The structure follows:
5539

56-
After running the command, it becomes a complete, self-contained schema:
57-
58-
```json
59-
"capabilities": {
60-
"type": "array",
61-
"description": "Meshery manages components...",
62-
"items": {
63-
"$id": "https://schemas.meshery.io/capability.json",
64-
"$schema": "http://json-schema.org/draft-07/schema#",
65-
"description": "Meshery manages entities...",
66-
"additionalProperties": false,
67-
"type": "object",
68-
"required": [
69-
"schemaVersion",
70-
"version",
71-
"displayName",
72-
"kind",
73-
"type",
74-
"entityState",
75-
"status"
76-
],
77-
"x-oapi-codegen-extra-tags": { // additional metadata tag
78-
"gorm": "type:bytes;serializer:json"
79-
}
80-
}
81-
}
40+
```
41+
schemas/
42+
constructs/
43+
<schema-version>/ # e.g., v1beta1
44+
<construct>/ # e.g., model, component
45+
<construct>.json # Schema definition for the construct (noun)
46+
subschemas/ # Any subschemas used within the construct
47+
openapi.yml # OpenAPI schema defining API operations (verbs like create, update, delete)
8248
```
8349

84-
**When to run this command?**
50+
### **Explanation**
51+
- **`constructs/`** – Contains schemas for different versions.
52+
- **`<schema-version>/`** – Each schema version (e.g., `v1beta1`, `v1alpha2`) is a separate directory.
53+
- **`<construct>/`** – Each construct (e.g., `capability`, `category`) has its own folder.
54+
- **`<construct>.json`** – Defines the **schema for the noun** (i.e., the entity).
55+
- **`subschemas/`** – Contains reusable subschemas for modularity.
56+
- **`openapi.yml`** – Defines **API operations** (verbs: `create`, `update`, `delete`) and serves as the **entry point** for the schema.
8557

86-
Whenever you:
87-
- Modify schema files
88-
- Add new schema references
89-
- Before generating Go code
90-
- When troubleshooting code generation issues
58+
This approach ensures that **schemas are well-organized, reusable, and scalable** across different Meshery components.
9159

92-
#### Code Generation and Configuration
60+
---
9361

94-
The code generation process uses two key configuration files:
95-
1. **scripts/config.yml**: Controls oapi-codegen behavior
62+
## **Adding a New Schema**
9663

97-
```yml
98-
package: organization # Set your desired package name
64+
To add a new schema, follow these steps:
65+
1. **Create a new directory** under `schemas/constructs/` for the new schema version.
66+
2. **Create a new directory** for the construct under the version directory.
67+
3. **Define the schema** in JSON format and save it as `<construct>.json`.
68+
4. **Create a subschemas directory** if needed, and add any reusable subschemas.
69+
5. **Define the OpenAPI schema** in `openapi.yml` to specify API operations.
70+
6. **Update the `generate.sh` script** to include the new schema for code generation.
71+
7. **Run the code generation script** to generate the necessary code files.
9972

100-
generate:
101-
models: true # Generate model structs
10273

103-
import-mapping: # Map schema references to Go imports
104-
"../v1beta1/model.json": "github.com/meshery/schemas/models/v1beta1/model"
105-
"../v1alpha1/capability.json": "github.com/meshery/schemas/models/v1alpha1/capability"
10674

107-
output: models/v1beta1/organization.go # Specify output file
108-
output-options:
109-
skip-prune: true
110-
include-tags: # Filter generated code by tags
111-
- organizations
112-
```
75+
## **Code Generation**
76+
Meshery supports **automatic code generation** for:
77+
- **Golang** (structs and types)
78+
- **TypeScript** (interfaces and types)
11379

114-
2. **schemas/constructs/openapi/models.yml**: Defines OpenAPI schema references
80+
### **Generating Code from Schemas**
81+
The schema-to-code mapping is defined in **`generate.sh`**, which automates the generation process.
11582

116-
```yml
117-
openapi: 3.0.0
118-
components:
119-
schemas:
120-
component_definition:
121-
$ref: ../v1beta1/component.json
83+
#### **Generating Golang Models**
84+
To generate Go structs from schemas, use:
85+
```bash
86+
make golang-generate
12287
```
12388

124-
#### Workflow
125-
126-
1. Update schema references in **models.yml**:
127-
- Uncomment/add needed schema references
128-
- Each reference generates corresponding Go structs
129-
2. Modify **config.yml**:
130-
- Set appropriate package name
131-
- Update output file path
132-
- Add required import mappings
133-
- Configure include-tags if needed
134-
3. Generate code:
89+
This also generates a merged_openapi.yml file which can be used to generate the redoc documentation and for rtk-api
13590

91+
#### **Generating TypeScript Models**
92+
To generate TypeScript types and and ts objects for the schemas use:
13693
```bash
137-
oapi-codegen -config scripts/config.yml schemas/constructs/openapi/models.yml
94+
make generate-ts
13895
```
13996

140-
**Key Points:**
141-
- Run `make resolve-ref` before code generation (only for JSON schemas)
142-
- Keep import mappings synchronized with schema references
143-
- Generated code inherits package name from config
144-
- Use tags to filter generated structs
145-
146-
### Handling Schema Changes and Field Ordering
147-
148-
When modifying schema structs or their fields, there are two common scenarios:
149-
150-
#### 1. Adding a New Field or Struct
151-
152-
- **Revert Logic:** If you add a new field, the entire file may change due to automated code generation. **What to do:**
153-
154-
- Identify the new field or struct you have added.
155-
156-
- Copy this new addition.
157-
158-
- Revert the rest of the file to its original state.
159-
160-
- Re-insert the new field or struct into its appropriate location.
161-
162-
>**Note:** We are working on streamlining this process, any contributions to improve automation are welcome! 🚀
97+
This will generate the typescript types and also javascript objects for the schemas
98+
the javascript objects can be used to do run time validation of data or for getting information from the schema
16399

164-
#### 2. Preserving Field Order with `x-order` Tag
165100

166-
- **x-order Tag Usage:** If you only add an `x-order` tag, it ensures fields remain in a specific order. **Steps:**
167-
168-
- Run the usual commands to resolve references and generate the code.
169-
170-
- If the field order changes unexpectedly, manually rearrange them.
171-
172-
- Commit the changes, ensuring the `x-order` tag is included to maintain order in future generations.
173-
174-
### Example
175-
176-
Let's walk through a practical example, you made some changes in the **component.json**
177-
1. First, ensure your schema references are resolved:
178-
179-
```yml
180-
make resolve-ref path="./schemas/constructs/v1beta1"
101+
### **Schema-to-Code Mapping**
102+
Example mapping in **`generate.sh`**:
103+
```bash
104+
generate_schema_models <construct> <schema-version>
105+
generate_schema_models "capability" "v1alpha1"
106+
generate_schema_models "category" "v1beta1"
107+
generate_schema_models "component" "v1beta1"
108+
generate_schema_models "pattern" "v1beta1" "schemas/constructs/v1beta1/design/openapi.yml"
109+
generate_schema_models "core" "v1alpha1"
110+
generate_schema_models "catalog" "v1alpha2"
181111
```
112+
- The **package name matches the construct name**.
113+
- Example: For the `capability` construct in `v1alpha1`, the generated Go code will be in:
114+
```
115+
models/v1alpha1/capability/capability.go
116+
```
182117

183-
2. Update `schemas/constructs/openapi/models.yml` to reference component.json:
184-
185-
```yml
186-
openapi: 3.0.0
187-
components:
188-
schemas:
189-
component_definition:
190-
$ref: ../v1beta1/component.json
118+
### **Example Output**
119+
```bash
120+
./generate-golang.sh
121+
🔹 Processing: capability (v1alpha1)...
122+
✅ Generated: models/v1alpha1/capability/capability.go
123+
🔹 Processing: category (v1beta1)...
124+
✅ Generated: models/v1beta1/category/category.go
125+
🔹 Processing: pattern (v1beta1)...
126+
✅ Generated: models/v1beta1/pattern/pattern.go
127+
🔹 Processing: core (v1alpha1)...
128+
✅ Generated: models/v1alpha1/core/core.go
129+
🔹 Processing: catalog (v1alpha2)...
130+
✅ Generated: models/v1alpha2/catalog/catalog.go
191131
```
192132

193-
3. Configure **config.yml**:
133+
This ensures that schemas remain the **single source of truth**, making development **efficient, consistent, and scalable**.
194134

195-
<code>
196-
package: component
197135

198-
generate:
199-
models: true
200136

201-
import-mapping:
202-
"../v1beta1/model.json": "github.com/meshery/schemas/models/v1beta1/model"
203-
"../v1alpha1/capability.json": "github.com/meshery/schemas/models/v1alpha1/capability"
204-
205-
output: models/v1beta1/component/component.go
206-
output-options:
207-
skip-prune: true
208-
include-tags:
209-
- components
210-
</code>
211-
212-
4. Generate code
213-
214-
```yml
215-
oapi-codegen -config scripts/config.yml schemas/constructs/openapi/models.yml
216-
```
217-
218-
### Contributing to Documentation
219-
220-
1. **Schema Documentation**
221-
- Add detailed descriptions in schema fields
222-
- Include example values where helpful
223-
- Document validation rules and constraints
224-
225-
```json
226-
{
227-
"displayName": {
228-
"type": "string",
229-
"description": "Human-readable name for the component.", // <-- description here
230-
"minLength": 1,
231-
"maxLength": 100,
232-
"examples": ["nginx-deployment"] // <-- examples
233-
}
234-
}
235-
```
236137

237138
### Getting Help
238139

0 commit comments

Comments
 (0)