Skip to content

Описание JSON-схемы

📐 Базовая структура

JSON схема состоит из нескольких разделов:

  1. table_name - имя DynamoDB таблицы
  2. hash_key / range_key - первичные ключи таблицы
  3. attributes - ключевые атрибуты для индексов
  4. common_attributes - обычные поля данных
  5. secondary_indexes - вторичные индексы (GSI/LSI)

🧾 Примеры

json
{
  "table_name": "users",
  "hash_key": "user_id",
  "attributes": [
    {"name": "user_id", "type": "S"}
  ],
  "common_attributes": [
    {"name": "email",     "type": "S"},
    {"name": "age",       "type": "N"},
    {"name": "is_active", "type": "BOOL"}
  ]
}
json
{
  "table_name": "user_posts",
  "hash_key": "user_id",
  "range_key": "created_at",
  "attributes": [
    {"name": "user_id",    "type": "S"},
    {"name": "created_at", "type": "S"},
    {"name": "status",     "type": "S"},
    {"name": "category",   "type": "S"},
    {"name": "priority",   "type": "N"}
  ],
  "common_attributes": [
    {"name": "title",      "type": "S"},
    {"name": "content",    "type": "S"},
    {"name": "tags",       "type": "SS"},
    {"name": "view_count", "type": "N"}
  ],
  "secondary_indexes": [
    {
      "name": "lsi_by_status",
      "type": "LSI",
      "range_key": "status",
      "projection_type": "KEYS_ONLY"
    },
    {
      "name": "gsi_by_category",
      "type": "GSI",
      "hash_key": "category",
      "range_key": "created_at",
      "projection_type": "ALL"
    },
    {
      "name": "gsi_by_status_priority",
      "type": "GSI",
      "hash_key": "status",
      "range_key": "priority",
      "projection_type": "INCLUDE",
      "non_key_attributes": ["title", "view_count"]
    }
  ]
}
json
{
  "table_name": "analytics_metrics",
  "hash_key": "user_id", 
  "range_key": "event_timestamp",
  "attributes": [
    {
      "name": "user_id",
      "type": "S"
    },
    {
      "name": "event_timestamp", 
      "type": "N",
      "subtype": "int64"
    }
  ],
  "common_attributes": [
    {
      "name": "session_count",
      "type": "N", 
      "subtype": "int32"
    },
    {
      "name": "conversion_rate",
      "type": "N",
      "subtype": "float32" 
    },
    {
      "name": "total_revenue_cents",
      "type": "N",
      "subtype": "uint64"
    },
    {
      "name": "priority_level",
      "type": "N",
      "subtype": "int16"
    },
    {
      "name": "test_scores",
      "type": "NS",
      "subtype": "int32"
    },
    {
      "name": "conversion_rates_history", 
      "type": "NS",
      "subtype": "float32"
    },
    {
      "name": "transaction_amounts",
      "type": "NS", 
      "subtype": "uint64"
    },
    {
      "name": "rating_values",
      "type": "NS",
      "subtype": "int16"
    },
    {
      "name": "daily_timestamps",
      "type": "NS",
      "subtype": "int64"
    }
  ],
  "secondary_indexes": []
}
json
{
  "table_name": "multi_tenant_posts",
  "hash_key": "tenant_id",
  "range_key": "post_created_at",
  "attributes": [
    {
      "name": "tenant_id", 
      "type": "S"
    },
    {
      "name": "post_created_at",
      "type": "S"
    },
    {
      "name": "user_id",
      "type": "S" 
    },
    {
      "name": "category",
      "type": "S"
    },
    {
      "name": "post_type",
      "type": "S"
    },
    {
      "name": "status",
      "type": "S"
    },
    {
      "name": "priority",
      "type": "N"
    }
  ],
  "common_attributes": [
    {
      "name": "title",
      "type": "S"
    },
    {
      "name": "content", 
      "type": "S"
    },
    {
      "name": "tags",
      "type": "SS"
    },
    {
      "name": "view_count",
      "type": "N"
    }
  ],
  "secondary_indexes": [
    {
      "name": "gsi_user_posts",
      "type": "GSI",
      "hash_key": "TENANT#tenant_id#user_id",
      "range_key": "post_created_at", 
      "projection_type": "ALL"
    },
    {
      "name": "gsi_category_posts",
      "type": "GSI", 
      "hash_key": "BLOG#tenant_id#category",
      "range_key": "post_created_at",
      "projection_type": "KEYS_ONLY"
    },
    {
      "name": "gsi_status_priority",
      "type": "GSI",
      "hash_key": "status#tenant_id", 
      "range_key": "META#post_type#priority",
      "projection_type": "INCLUDE",
      "non_key_attributes": ["title", "view_count"]
    },
    {
      "name": "lsi_by_user",
      "type": "LSI",
      "range_key": "USER#user_id#post_type",
      "projection_type": "ALL"
    }
  ]
}

🔒 Обязательные поля

table_name

Тип: string
Пример: "user_profiles"

Логическое имя DynamoDB таблицы.

Используется для генерации:

  • Имени Go пакета (в нижнем регистре)
  • Имени файла (table_name.go)
  • Константы TableName в коде

пакет userprofiles, файл userprofiles.go


hash_key

Тип: string
Пример: "user_id"

Первичный ключ раздела (partition key) DynamoDB таблицы.

Должен ссылаться на один из атрибутов из массива attributes.


attributes

Тип: array of objects
Пример: {"name": "user_id", "type": "S"}

Массив ключевых атрибутов

Используются в первичных ключах и индексах.

Состоит из:

  • name

    Тип: string
    Пример: "user_id"

    Имя атрибута

    Должно быть уникальным в пределах всех атрибутов таблицы.

  • type

    Тип: string
    Пример: "S"

    DynamoDB тип данных

    DynamoDB типGo типОписание
    "S"stringСтрока
    "N"int64Число
    "BOOL"boolБулево значение
    "SS"[]stringМножество строк
    "NS"[]intМножество чисел
    "string"stringАлиас для "S"
    "number"int64Алиас для "N"
    "boolean"boolАлиас для "BOOL"
  • subtype

    Тип: string (опциональное поле)
    Пример: "uint64"

    Уточняет Go тип

    Применимо только для типов "N" и "NS"

    DynamoDB типSubtypeGo типОписание
    "N""int32"int3232-битное целое
    "N""int64"int6464-битное целое (по умолчанию)
    "N""float32"float3232-битное число с плавающей точкой
    "N""uint64"uint6464-битное беззнаковое целое
    "N""int16"int1616-битное целое
    "NS""int32"[]int32Множество 32-битных целых
    "NS""int64"[]int64Множество 64-битных целых
    "NS""float32"[]float32Множество чисел с плавающей точкой
    "NS""uint64"[]uint64Множество беззнаковых целых
    "NS""int16"[]int16Множество 16-битных целых

🔓 Опциональные поля

range_key

Тип: string
Пример: "timestamp"

Первичный ключ сортировки (sort key) DynamoDB таблицы.

Если указан, должен ссылаться на один из атрибутов из массива attributes.


common_attributes

Тип: array of objects
Пример: {"name": "email", "type": "S"}

Массив обычных атрибутов для хранения данных.

Эти атрибуты НЕ могут использоваться в ключах индексов, только для хранения информации.

Структура объекта аналогична attributes


secondary_indexes

Тип: array of objects

Массив вторичных индексов (GSI и LSI) для расширенных возможностей запросов.

Состоит из:

  • name

    Тип: string
    Пример: "user_id"

    Имя атрибута

    Уникальное имя индекса в пределах таблицы.

  • type

    Тип: string
    Пример: "GSI"

    Тип индекса

    • GSI (Global Secondary Index) - может иметь любой hash_key
    • LSI (Local Secondary Index) - использует hash_key основной таблицы
  • hash_key

    Тип: string
    Обязательный: Для GSI - да, для LSI - нет

    Ключ сортировки для индекса

    Должен ссылаться на атрибут из attributes и отличаться от range_key основной таблицы (для LSI).

  • projection_type

    Тип: string
    Значения: "ALL", "KEYS_ONLY", "INCLUDE"

    Определяет, какие атрибуты включены в индекс

    • ALL - все атрибуты основной таблицы
    • KEYS_ONLY - только ключевые атрибуты индекса и таблицы
    • INCLUDE - ключи + атрибуты из non_key_attributes
  • non_key_attributes

    Тип: array of strings
    Обязательный: Только когда projection_type = "INCLUDE"

    Список дополнительных атрибутов для включения в индекс

  • read_capacity и write_capacity

    Тип: integer
    Обязательный: Нет

    Настройки пропускной способности для GSI

    LSI использует настройки основной таблицы.

    Только для: GSI

🔑 Композитные ключи

json
{
  "name": "user_status_index",
  "type": "GSI",
  "hash_key": "user_id#status",
  "range_key": "created_at"
}

Композитный ключ user_id#status создает ключ из комбинации атрибутов user_id и status.

🛡️ Валидация

GoDyno автоматически проверяет:

  • Все ключи ссылаются на существующие атрибуты
  • Уникальность имен индексов
  • Корректность типов проекции
  • Соответствие non_key_attributes типу проекции INCLUDE
  • LSI имеет обязательный range_key
  • GSI имеет обязательный hash_key
  • Range key LSI отличается от range key таблицы

При ошибках валидации генерация кода завершится с детальным описанием проблемы.

Выпущено под лицензией MIT.