feat: add logger and adjust reflection#63
Conversation
- Types implementing encoding.TextMarshaler+TextUnmarshaler (without json.Marshaler) are now reflected as type:string schemas. - Add openapi.EmbedReferencer interface and refer:"true" struct tag: embedded structs opt into allOf $ref instead of field inlining. - Fix RefSchema to propagate AllOf from StructSchema into component. - Add golden tests for embed_ref case across all three OAS versions.
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
AI Code Review by LlamaPReview
🎯 TL;DR & Recommendation
Recommendation: Request Changes
This PR adds valuable logger integration, TextMarshaler/EmbedRef support, and automatic form content-type inference, but introduces a breaking change in struct tags (formData → form) that will silently break existing user-defined types. A critical golden file for the new embed_ref test is also missing, causing test failures.
📄 Documentation Diagram
This diagram documents the new reflection features: TextMarshaler detection, EmbedReferencer allOf $ref, and automatic form content-type inference.
sequenceDiagram
participant Client
participant Reflector
participant Builder
Client->>Reflector: SchemaForType(t, mode, field)
Reflector->>Reflector: Check isTextMarshaler(t)
alt TextMarshaler without json.Marshaler
Reflector->>Reflector: Return string schema
else Not TextMarshaler
Reflector->>Reflector: Normal type switch (int, string, etc.)
end
Client->>Reflector: StructSchema(t, nameTag, onlyTagged, mode)
Reflector->>Reflector: Pre-scan anonymous fields for refer:"true" or EmbedReferencer
note over Reflector: PR #35;63: new EmbedRef support
alt Is embed ref
Reflector->>Reflector: Generate component via RefSchema
Reflector->>Reflector: Append allOf $ref to parent schema
else Normal embed
Reflector->>Reflector: Inline fields
end
Client->>Builder: ContentType(cu)
Builder->>Builder: Check InferContentType(cu.Structure)
note over Builder: PR #35;63: automatic content-type detection
alt Form tag present
alt File type found
Builder->>Builder: Return multipart/form-data
else No file type
Builder->>Builder: Return application/x-www-form-urlencoded
end
else No form tag
Builder->>Builder: Use explicit ContentType or fallback to application/json
end
🌟 Strengths
- Solid new feature additions (logger, TextMarshaler, EmbedRef, form content-type inference) with good test coverage.
⚡ Key Risks & Improvements (P1)
- internal/testutil/dto/types.go: The
formData→formtag rename is a breaking API change; external users withformDatatags will lose automatic form recognition. Add backward compatibility or document the migration.
💡 Suggestions (P2)
- golden_test.go: The
embed_refgolden test is added without the corresponding golden file – tests will fail on checkout. Runmake test-updateand commit the generated file.
📈 Risk Diagram
This diagram illustrates the risk of the formData→form tag migration breaking existing user structs.
sequenceDiagram
participant User
participant Reflector
participant Builder
User->>Reflector: Struct with formData tags (legacy)
Reflector->>Reflector: InferContentType looks only for form tag
note over Reflector: R1(P1): Legacy formData tags ignored
Reflector->>Builder: Body tag empty → no form fields
Builder->>Builder: ContentType defaults to application/json
note over Builder: R1(P1): Struct fields not extracted as form parameters
Builder->>User: Generated schema missing form fields
User->>User: Expected application/x-www-form-urlencoded body with fields, got empty
💡 Have feedback? We'd love to hear it in our GitHub Discussions.
✨ This review was generated by LlamaPReview Advanced, which is free for all open-source projects. Learn more.
Add ParameterInBody and ParameterInForm constants. When set in ParameterTagMapping, they override the struct tag used to name JSON body fields (default "json") and form body fields (default "form"). ParameterField skips these two keys so body-tagged fields are not misidentified as HTTP parameters.
Previously, def names were unqualified for types in the caller package (detected via runtime stack walking), and prefixed only for external packages. This caused cross-package name collisions and relied on fragile runtime introspection. Now all named types are prefixed with their Go package name, matching openapi-go / jsonschema-go behavior: - models.User → ModelsUser - dto.Pet → DtoPet Multi-segment package names are sanitized to UpperCamel (spec_test → SpecTest). Unexported type names are title-cased on join. BREAKING CHANGE: generated $ref component schema names gain a package prefix. Existing OpenAPI documents will have different schema keys. Use InterceptDefName or StripDefNamePrefix to strip the prefix if the old names are required. Removed: DefNameCallerPkg field on ReflectorConfig, ensureCallerPkgForDefName, callerPackagePath, packagePathFromFunc.
Description
Closes #
Type of Change
Checklist
make checkpasses locally (sync + tidy + lint + test)make test-update)