Skip to content

Commit 5caeadf

Browse files
committed
[docs] Document avoiding embedded structs in config structures
Add guidelines to coding-guidelines.md explaining why embedded structs should be avoided in configuration definitions. This helps prevent unmarshal issues, naming conflicts, and improves code clarity. Fixes #12719
1 parent ad49dc6 commit 5caeadf

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: enhancement
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. receiver/otlp)
7+
component: docs
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Add documentation guidelines for avoiding embedded structs in configuration
11+
12+
# One or more tracking issues or pull requests related to the change
13+
issues: [12719]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext: |
19+
Added a new section to coding-guidelines.md explaining why embedded structs should be
20+
avoided in configuration definitions, including examples showing the preferred approach.
21+
22+
# Optional: The change log or logs in which this entry should be included.
23+
# e.g. '[user]' or '[user, api]'
24+
# Include 'user' if the change is relevant to end users.
25+
# Include 'api' if there is a change to a library API.
26+
# Default: '[user]'
27+
change_logs: []

docs/coding-guidelines.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,38 @@ When naming configuration structs, use the following guidelines:
4747
- Use the `Settings` suffix for configuration structs that are set by developers in the code. For example, `component.TelemetrySettings` ends in `Settings` since it is set by developers in the code.
4848
- Avoid redundant prefixes that are already implied by the package name. For example, use`configgrpc.ClientConfig` instead of `configgrpc.GRPCClientConfig`.
4949

50+
#### Avoid Embedded Structs
51+
52+
When defining configuration structs, avoid using embedded (anonymous) struct fields. Instead, use explicitly named fields.
53+
54+
**Rationale:**
55+
56+
1. **Unmarshal Compatibility**: Embedded structs can break custom `Unmarshal` implementations. If an embedded struct requires special unmarshaling logic, it may not function correctly when embedded.
57+
58+
2. **Naming Conflicts**: Embedded structs can cause field name collisions. Even if the YAML configuration nests them properly (e.g., under `sending_queue`), having identical field names in embedded structs creates ambiguity in the Go code.
59+
60+
3. **Clarity**: Named fields make the configuration structure more explicit and easier to understand.
61+
62+
**Example:**
63+
64+
```go
65+
// ❌ BAD: Using embedded structs
66+
type ExporterConfig struct {
67+
exporterhelper.TimeoutConfig // embedded
68+
exporterhelper.QueueConfig // embedded
69+
exporterhelper.RetryConfig // embedded
70+
}
71+
72+
// ✅ GOOD: Using named fields
73+
type ExporterConfig struct {
74+
Timeout exporterhelper.TimeoutConfig `mapstructure:"timeout"`
75+
Queue exporterhelper.QueueConfig `mapstructure:"sending_queue"`
76+
Retry exporterhelper.RetryConfig `mapstructure:"retry_on_failure"`
77+
}
78+
```
79+
80+
This practice ensures better maintainability and prevents subtle bugs related to struct composition and configuration unmarshaling.
81+
5082
## Module organization
5183

5284
As usual in Go projects, organize your code into packages grouping related functionality. To ensure

0 commit comments

Comments
 (0)