Дата: 2025-11-10
Версия: 1.0.0
Цель: Изучить лучшие мировые стандарты, взять лучшее или создать своё
Создать СВОЙ стандарт, объединяющий лучшее:
- OpenAPI (описание API endpoints)
- JSON Schema (валидация полей)
- Prisma (синтаксис полей и отношений)
- Terraform (декларативность)
OpenAPI Specification - индустриальный стандарт описания REST API.
Кто использует: AWS, Google Cloud, Microsoft Azure, Stripe, GitHub, Shopify
Версия: OpenAPI 3.1 (актуальная)
openapi: 3.1.0
info:
title: User API
version: 1.0.0
components:
schemas:
User:
type: object
required:
- id
- email
properties:
id:
type: integer
format: int64
email:
type: string
format: email
maxLength: 255
username:
type: string
minLength: 3
maxLength: 100
age:
type: integer
minimum: 0
maximum: 150
is_active:
type: boolean
default: true
created_at:
type: string
format: date-time
readOnly: true
paths:
/users:
get:
summary: Список пользователей
operationId: listUsers
parameters:
- name: limit
in: query
schema:
type: integer
default: 100
responses:
'200':
description: Успешный ответ
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
post:
summary: Создать пользователя
operationId: createUser
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/User'
responses:
'201':
description: Пользователь создан
content:
application/json:
schema:
$ref: '#/components/schemas/User'
/users/{id}:
get:
summary: Получить пользователя
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Успешный ответ
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'404':
description: Пользователь не найден
Существующие генераторы:
# OpenAPI Generator (официальный)
openapi-generator generate \
-i openapi.yaml \
-g python-fastapi \
-o ./generated
# Генерирует:
# - FastAPI endpoints
# - Pydantic models
# - Tests
# - Documentation
# Другие языки:
# -g java-spring
# -g typescript-axios
# -g go-gin
# -g rust-server
Python библиотеки:
# 1. datamodel-code-generator (Pydantic из OpenAPI)
pip install datamodel-code-generator
datamodel-codegen \
--input openapi.yaml \
--output models.py \
--input-file-type openapi
# 2. fastapi-code-generator
pip install fastapi-code-generator
fastapi-codegen \
--input openapi.yaml \
--output app
JSON Schema - стандарт описания структуры JSON данных.
Официальный сайт: json-schema.org
Версия: Draft 2020-12
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/user.schema.json",
"title": "User",
"description": "Пользователь системы",
"type": "object",
"required": ["id", "email"],
"properties": {
"id": {
"type": "integer",
"description": "Уникальный идентификатор"
},
"email": {
"type": "string",
"format": "email",
"maxLength": 255
},
"username": {
"type": "string",
"minLength": 3,
"maxLength": 100,
"pattern": "^[a-zA-Z0-9_]+$"
},
"age": {
"type": "integer",
"minimum": 0,
"maximum": 150
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
},
"address": {
"type": "object",
"properties": {
"street": {"type": "string"},
"city": {"type": "string"},
"zip": {"type": "string", "pattern": "^[0-9]{5}$"}
}
}
}
}
Python библиотеки:
# 1. datamodel-code-generator
datamodel-codegen \
--input schema.json \
--output models.py
# Генерирует Pydantic модели
# 2. jsonschema2popo (JSON Schema → Python Objects)
pip install jsonschema2popo
Пример сгенерированного кода:
# Из JSON Schema выше генерируется:
from pydantic import BaseModel, Field, EmailStr
from typing import Optional, List
class Address(BaseModel):
street: Optional[str] = None
city: Optional[str] = None
zip: Optional[str] = Field(None, regex=r"^[0-9]{5}$")
class User(BaseModel):
"""Пользователь системы"""
id: int = Field(..., description="Уникальный идентификатор")
email: EmailStr = Field(..., max_length=255)
username: str = Field(..., min_length=3, max_length=100, regex=r"^[a-zA-Z0-9_]+$")
age: Optional[int] = Field(None, ge=0, le=150)
tags: Optional[List[str]] = Field(None, unique_items=True)
address: Optional[Address] = None
Prisma - современный ORM для Node.js/TypeScript с собственным DSL.
Сайт: prisma.io
Особенность: Очень лаконичный синтаксис
// schema.prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id Int @id @default(autoincrement())
email String @unique
username String @unique
password String
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
posts Post[]
profile Profile?
@@index([email])
@@index([username])
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
authorId Int
author User @relation(fields: [authorId], references: [id])
@@index([authorId])
}
model Profile {
id Int @id @default(autoincrement())
bio String?
avatar String?
userId Int @unique
user User @relation(fields: [userId], references: [id])
}
# 1. Генерация миграций
prisma migrate dev --name add_users
# 2. Генерация клиента (TypeScript)
prisma generate
# Создаётся:
# - TypeScript типы
# - Prisma Client (ORM)
# - Миграции SQL
Сгенерированный код (TypeScript):
// Автогенерация типов и клиента
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
// Типобезопасные запросы
const user = await prisma.user.create({
data: {
email: 'test@example.com',
username: 'testuser',
password: 'hash',
posts: {
create: [
{ title: 'Hello World', content: 'My first post' }
]
}
},
include: {
posts: true
}
})
SQLModel (от создателя FastAPI):
from sqlmodel import SQLModel, Field, Relationship
from typing import Optional, List
class User(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
email: str = Field(unique=True, index=True)
username: str = Field(unique=True, index=True)
password: str
is_active: bool = True
posts: List["Post"] = Relationship(back_populates="author")
class Post(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
title: str
content: Optional[str] = None
author_id: int = Field(foreign_key="user.id")
author: User = Relationship(back_populates="posts")
Похоже на Prisma, но менее лаконично.
GraphQL SDL - язык описания схемы GraphQL API.
Кто использует: Facebook, GitHub, Shopify, Airbnb
type User {
id: ID!
email: String!
username: String!
age: Int
isActive: Boolean!
createdAt: DateTime!
posts: [Post!]!
profile: Profile
}
type Post {
id: ID!
title: String!
content: String
published: Boolean!
author: User!
}
type Profile {
id: ID!
bio: String
avatar: String
user: User!
}
type Query {
users(limit: Int = 100, offset: Int = 0): [User!]!
user(id: ID!): User
posts(authorId: ID): [Post!]!
}
type Mutation {
createUser(email: String!, username: String!, password: String!): User!
updateUser(id: ID!, email: String, username: String): User!
deleteUser(id: ID!): Boolean!
}
schema {
query: Query
mutation: Mutation
}
GraphQL Code Generator:
npm install -g @graphql-codegen/cli
# codegen.yml
schema: schema.graphql
generates:
./src/generated/graphql.ts:
plugins:
- typescript
- typescript-resolvers
# Генерация
graphql-codegen
Для Python:
pip install graphene-django
# Генерирует Django модели из GraphQL схемы
Protocol Buffers (protobuf) - язык описания структур данных от Google.
Использование: gRPC, Google APIs, микросервисы
syntax = "proto3";
package user;
message User {
int64 id = 1;
string email = 2;
string username = 3;
int32 age = 4;
bool is_active = 5;
google.protobuf.Timestamp created_at = 6;
repeated Post posts = 7;
}
message Post {
int64 id = 1;
string title = 2;
string content = 3;
bool published = 4;
int64 author_id = 5;
}
service UserService {
rpc GetUser (GetUserRequest) returns (User);
rpc ListUsers (ListUsersRequest) returns (ListUsersResponse);
rpc CreateUser (CreateUserRequest) returns (User);
}
message GetUserRequest {
int64 id = 1;
}
message ListUsersRequest {
int32 limit = 1;
int32 offset = 2;
}
message ListUsersResponse {
repeated User users = 1;
int32 total = 2;
}
message CreateUserRequest {
string email = 1;
string username = 2;
string password = 3;
}
# Генерация Python кода
protoc --python_out=. user.proto
# Генерация для других языков
protoc --go_out=. user.proto
protoc --java_out=. user.proto
protoc --csharp_out=. user.proto
HCL (HashiCorp Configuration Language) - декларативный язык для инфраструктуры.
Использование: Terraform, Vault, Consul
resource "aws_instance" "web_server" {
ami = "ami-12345678"
instance_type = "t2.micro"
tags = {
Name = "WebServer"
Environment = "Production"
}
}
resource "aws_db_instance" "database" {
engine = "postgres"
instance_class = "db.t3.micro"
allocated_storage = 20
db_name = "myapp"
username = "admin"
password = var.db_password
}
variable "db_password" {
type = string
sensitive = true
}
output "server_ip" {
value = aws_instance.web_server.public_ip
}
terraform plan показывает что изменитсяДекларативность + План изменений
# Описываешь желаемое состояние
entity: User
fields:
- name: email
# Генератор показывает план:
Plan:
+ Create model User
+ Create schema UserCreate
+ Create endpoint POST /users
+ Create migration 001_create_users
AsyncAPI - стандарт описания асинхронных API (message brokers).
Использование: Kafka, RabbitMQ, WebSocket
asyncapi: 2.6.0
info:
title: User Events API
version: 1.0.0
channels:
user/created:
subscribe:
message:
payload:
type: object
properties:
id:
type: integer
email:
type: string
created_at:
type: string
format: date-time
user/updated:
subscribe:
message:
payload:
type: object
properties:
id:
type: integer
email:
type: string
| Стандарт | Область | Формат | Генерация | Экосистема | Лаконичность |
|---|---|---|---|---|---|
| OpenAPI | REST API | YAML/JSON | ✅ Отличная | ⭐⭐⭐⭐⭐ | 🟡 Verbose |
| JSON Schema | Данные | JSON | ✅ Хорошая | ⭐⭐⭐⭐⭐ | 🟡 Verbose |
| Prisma | ORM | .prisma | ✅ Отличная | ⭐⭐⭐⭐ | ✅ Лаконично |
| GraphQL | GraphQL API | .graphql | ✅ Отличная | ⭐⭐⭐⭐⭐ | ✅ Хорошо |
| Protobuf | gRPC | .proto | ✅ Отличная | ⭐⭐⭐⭐⭐ | ✅ Хорошо |
| Terraform | Инфраструктура | HCL | ✅ Отличная | ⭐⭐⭐⭐⭐ | ✅ Отлично |
| AsyncAPI | Events | YAML | 🟡 Средняя | ⭐⭐⭐ | 🟡 Verbose |
Описание:
├── Entity (модель БД) ← Prisma подход
├── API endpoints ← OpenAPI подход
├── Валидация полей ← JSON Schema
└── Декларативность ← Terraform подход
Ни один стандарт не покрывает всё!
Философия: Взять лучшее из всех стандартов.
# User.cidl - полное описание сущности
schema:
version: "1.0"
generator: "cifra-codegen-v1"
entity:
name: User
table: users
description: "Пользователь системы"
fields:
id:
type: integer
db:
primary_key: true
auto_increment: true
api:
read_only: true
email:
type: string
constraints:
format: email
max_length: 255
unique: true
db:
index: true
api:
required: true
writable: create # только при создании
username:
type: string
constraints:
min_length: 3
max_length: 100
pattern: "^[a-zA-Z0-9_]+$"
unique: true
db:
index: true
api:
required: true
password:
type: string
constraints:
min_length: 8
db:
column_name: password_hash
api:
write_only: true # не возвращается в API
age:
type: integer
constraints:
minimum: 0
maximum: 150
api:
required: false
is_active:
type: boolean
default: true
api:
required: false
created_at:
type: datetime
db:
auto_now_add: true
index: true
api:
read_only: true
updated_at:
type: datetime
db:
auto_now: true
api:
read_only: true
relationships:
posts:
type: one_to_many
entity: Post
foreign_key: author_id
api:
include: optional # ?include=posts
profile:
type: one_to_one
entity: Profile
foreign_key: user_id
api:
include: optional
indexes:
- fields: [email]
unique: true
- fields: [username]
unique: true
- fields: [created_at, is_active]
name: active_users_by_date
api:
base_path: /users
endpoints:
list:
enabled: true
method: GET
path: ""
auth: required
permissions: [authenticated]
pagination: true
filters:
- field: is_active
type: boolean
- field: created_at
type: date_range
sorting:
- field: created_at
direction: desc
- field: username
get:
enabled: true
method: GET
path: "/{id}"
auth: required
permissions: [authenticated]
create:
enabled: true
method: POST
path: ""
auth: optional # публичная регистрация
permissions: [anonymous]
update:
enabled: true
method: PUT
path: "/{id}"
auth: required
permissions: [owner, admin]
delete:
enabled: true
method: DELETE
path: "/{id}"
auth: required
permissions: [admin]
permissions:
rules:
owner: "user.id == resource.id"
admin: "user.role == 'admin'"
validation:
custom_validators:
- name: unique_email_username
check: "email not in existing_emails AND username not in existing_usernames"
message: "Email or username already exists"
events:
on_create:
- emit: user.created
payload: {id, email, username}
on_update:
- emit: user.updated
payload: {id, email}
on_delete:
- emit: user.deleted
payload: {id}
testing:
fixtures:
- email: "test@example.com"
username: "testuser"
password: "password123"
age: 25
factories:
default:
email: "user{n}@example.com"
username: "user{n}"
password: "password123"
cifra-codegen generate User.cidl
# Генерируется:
generated/
├── models/
│ └── user.py # SQLAlchemy модель
│
├── schemas/
│ ├── user_create.py # Pydantic CreateSchema
│ ├── user_update.py # Pydantic UpdateSchema
│ └── user_response.py # Pydantic ResponseSchema
│
├── api/
│ └── users.py # FastAPI endpoints (CRUD + фильтры)
│
├── permissions/
│ └── user_permissions.py # Проверки доступа
│
├── events/
│ └── user_events.py # Event emitters
│
├── migrations/
│ └── 001_create_users.py # Alembic миграция
│
├── tests/
│ ├── test_user_model.py # Тесты модели
│ ├── test_user_api.py # Тесты API
│ └── fixtures/
│ └── users.py # Фикстуры
│
└── docs/
├── user_api.md # Документация API
└── user_openapi.yaml # OpenAPI спецификация
Один файл = всё:
- ✅ Модель БД (таблица, индексы)
- ✅ API endpoints
- ✅ Валидация
- ✅ Permissions
- ✅ Events
- ✅ Tests
Сравнение:
| Что описывает | OpenAPI | Prisma | CIDL |
|---|---|---|---|
| БД модель | ❌ | ✅ | ✅ |
| API endpoints | ✅ | ❌ | ✅ |
| Валидация | ✅ | 🟡 | ✅ |
| Permissions | ❌ | ❌ | ✅ |
| Events | ❌ | ❌ | ✅ |
| Tests | ❌ | ❌ | ✅ |
# Описываешь ЧТО нужно, а не КАК
fields:
email:
type: string
constraints:
format: email
unique: true
Генератор знает КАК:
- SQLAlchemy: Column(String, unique=True)
- Pydantic: EmailStr
- FastAPI: автовалидация
- Alembic: миграция с UNIQUE constraint
- Tests: проверка уникальности
fields: # Структура данных
...
db: # База данных
indexes:
constraints:
api: # REST API
endpoints:
permissions:
events: # Event-driven
on_create:
on_update:
testing: # Автотесты
fixtures:
factories:
Каждый аспект независим - можно генерировать выборочно.
Claude легко понимает и генерирует CIDL:
Пользователь: "Создай User с email, password, и ролями"
Claude API:
↓ генерирует CIDL
entity:
name: User
fields:
email:
type: string
constraints: {format: email, unique: true}
password:
type: string
constraints: {min_length: 8}
role:
type: enum
values: [user, admin]
default: user
↓ Code Generator
Готовые файлы
Кастомные секции:
# Можно добавлять свои секции
analytics:
track_changes: true
metrics:
- count_by_role
- active_users_daily
export:
formats: [csv, excel, pdf]
fields: [id, email, created_at]
notifications:
on_create:
- type: email
template: welcome_email
to: "{email}"
# cifra_codegen/
├── parser.py # CIDL → Python dict
├── validator.py # Валидация CIDL
├── generators/
│ ├── base.py # BaseGenerator
│ ├── sqlalchemy.py # SQLAlchemy генератор
│ ├── pydantic.py # Pydantic генератор
│ ├── fastapi.py # FastAPI генератор
│ ├── alembic.py # Alembic генератор
│ ├── tests.py # Tests генератор
│ └── docs.py # Documentation генератор
├── templates/ # Jinja2 шаблоны
└── cli.py # CLI интерфейс
# Установка
pip install cifra-codegen
# Генерация
cifra-codegen generate User.cidl --output ./generated
# Генерация только API
cifra-codegen generate User.cidl --only api
# С AI (Claude генерирует CIDL)
cifra-codegen ai "Создай User с email и password"
Итого: 6 недель до полной версии
Создать свой CIDL (CIFRA Interface Definition Language):
OpenAPI (API endpoints)
+ Prisma (лаконичность)
+ JSON Schema (валидация)
+ Terraform (декларативность)
+ Наши идеи (permissions, events, testing)
= CIDL
Q1: Начинаем разрабатывать CIDL?
Q2: Какие секции добавить в первую версию? (entity, fields, api - минимум)
Q3: Формат YAML или создать свой DSL (как Prisma)?
Версия: 1.0.0
Статус: Концепция готова
Следующий шаг: Начать разработку CIDL генератора?