docs: подводные камни от Соннета (Required+Default, json-теги, value_list)
This commit is contained in:
@@ -83,13 +83,15 @@ if v == "map-fixed" || v == "array-map-fixed" {
|
|||||||
|
|
||||||
**map-fixed** (один объект) → `schema.SingleNestedAttribute`:
|
**map-fixed** (один объект) → `schema.SingleNestedAttribute`:
|
||||||
```go
|
```go
|
||||||
|
// ⚠️ Подполя с default → Optional+Computed+Default (см. 4.1)
|
||||||
|
// Подполя без default → Required
|
||||||
"clusterConfiguration": schema.SingleNestedAttribute{
|
"clusterConfiguration": schema.SingleNestedAttribute{
|
||||||
Required: true,
|
Required: true,
|
||||||
Attributes: map[string]schema.Attribute{
|
Attributes: map[string]schema.Attribute{
|
||||||
"cpu": schema.Int64Attribute{Required: true, ...},
|
"cpu": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500)},
|
||||||
"memory": schema.Int64Attribute{Required: true, Default: int64default.StaticInt64(512)},
|
"memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512)},
|
||||||
"replicas": schema.Int64Attribute{Required: true, Default: int64default.StaticInt64(1)},
|
"replicas": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1)},
|
||||||
"disk": schema.Int64Attribute{Required: true, Default: int64default.StaticInt64(10)},
|
"disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(10)},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
@@ -113,11 +115,12 @@ if v == "map-fixed" || v == "array-map-fixed" {
|
|||||||
|
|
||||||
Для `clusterConfiguration` → `PostgresClusterConfigurationModel`:
|
Для `clusterConfiguration` → `PostgresClusterConfigurationModel`:
|
||||||
```go
|
```go
|
||||||
|
// ⚠️ json-теги = оригинальный code (camelCase), tfsdk-теги = snake_case (см. 4.2)
|
||||||
type PostgresClusterConfigurationModel struct {
|
type PostgresClusterConfigurationModel struct {
|
||||||
Cpu types.Int64 `tfsdk:"cpu"`
|
Cpu types.Int64 `tfsdk:"cpu" json:"cpu"`
|
||||||
Memory types.Int64 `tfsdk:"memory"`
|
Memory types.Int64 `tfsdk:"memory" json:"memory"`
|
||||||
Replicas types.Int64 `tfsdk:"replicas"`
|
Replicas types.Int64 `tfsdk:"replicas" json:"replicas"`
|
||||||
Disk types.Int64 `tfsdk:"disk"`
|
Disk types.Int64 `tfsdk:"disk" json:"disk"`
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -223,3 +226,56 @@ map — обратная конвертация из JSON в nested struct не
|
|||||||
- В Schema: `SingleNestedAttribute` / `ListNestedAttribute`
|
- В Schema: `SingleNestedAttribute` / `ListNestedAttribute`
|
||||||
- В Create/Modify: сериализация в JSON по родительскому ID
|
- В Create/Modify: сериализация в JSON по родительскому ID
|
||||||
6. Протестировать на postgres (самый сложный — 8 map-fixed + 1 array-map-fixed)
|
6. Протестировать на postgres (самый сложный — 8 map-fixed + 1 array-map-fixed)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Блок 4. Подводные камни (найдены Соннетом при сверке с terraform-plugin-framework)
|
||||||
|
|
||||||
|
### 4.1 — Конфликт Required + Default (БЛОКИРУЮЩИЙ)
|
||||||
|
|
||||||
|
Во фреймворке атрибут не может быть одновременно `Required` и иметь `Default`.
|
||||||
|
`Default` работает только с `Optional + Computed`.
|
||||||
|
|
||||||
|
А sub_params имеют `required: true` И `default` одновременно:
|
||||||
|
```yaml
|
||||||
|
sub_params:
|
||||||
|
- code: cpu
|
||||||
|
required: true
|
||||||
|
default: 500
|
||||||
|
- code: memory
|
||||||
|
required: true
|
||||||
|
default: 512
|
||||||
|
```
|
||||||
|
|
||||||
|
**Решение**: для подполей с default → `Optional + Computed + Default`.
|
||||||
|
Для подполей без default → `Required` без Default.
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Есть default:
|
||||||
|
schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500)}
|
||||||
|
// Нет default:
|
||||||
|
schema.Int64Attribute{Required: true}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 — JSON-ключи для API (БЛОКИРУЮЩИЙ)
|
||||||
|
|
||||||
|
`tfsdk`-теги генерятся в snake_case (`cluster_configuration`), но API ждёт
|
||||||
|
оригинальный camelCase code (`cpu`, `memory`, `replicas`).
|
||||||
|
|
||||||
|
`json.Marshal` struct'а с tfsdk-тегами даст неверные ключи при сериализации
|
||||||
|
map-fixed → JSON для отправки в API.
|
||||||
|
|
||||||
|
**Решение**: генерировать отдельные `json`-теги = оригинальный `code`:
|
||||||
|
```go
|
||||||
|
type PostgresClusterConfigurationModel struct {
|
||||||
|
Cpu types.Int64 `tfsdk:"cpu" json:"cpu"`
|
||||||
|
Memory types.Int64 `tfsdk:"memory" json:"memory"`
|
||||||
|
Replicas types.Int64 `tfsdk:"replicas" json:"replicas"`
|
||||||
|
Disk types.Int64 `tfsdk:"disk" json:"disk"`
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.3 — value_list подполей (out of scope)
|
||||||
|
|
||||||
|
Подполя имеют `value_list` (например `replicas: [1,3,5,7]`, `version: ["17","16"]`).
|
||||||
|
Генерация enum-валидаторов — на этом этапе не делать. Оставить на будущее.
|
||||||
|
|||||||
Reference in New Issue
Block a user