Open bendbennett opened 11 months ago
I'm a little confused about what is being proposed here 😅
"request": {
"timeout_minutes": {
"name": "MinutesTimeout",
},
"response": {
"MinutesTimeoutReturnedVal": {
"name": "timeout_minutes",
}
}
Seems to suggest that there might be two Go type definitions for the same type with different fields. I would have expected it to be multiple types involved, so it would require specifying the import and second type, e.g.
package imagebuilder
type ImageTestsConfiguration struct {
MinutesTimeout // ...
}
type SomethingElse struct {
MinutesTimeoutReturnedVal // ...
}
I was under the presumption that at some point, if we needed support for multiple associated external types, we would support it as an array of associated external types each with its own attribute name mapping. In the above:
"associated_external_types": [
{
"imports": [
{
"path": "github.com/aws/aws-sdk-go/service/imagebuilder"
}
],
"type": "*imagebuilder.ImageTestsConfiguration",
"mapping": {
"timeout_minutes": {
"name": "MinutesTimeout",
}
}
},
{
"imports": [
{
"path": "github.com/aws/aws-sdk-go/service/imagebuilder"
}
],
"type": "*imagebuilder.SomethingElse",
"mapping": {
"timeout_minutes": {
"name": "MinutesTimeoutReturnedVal",
}
}
}
]
Then, a separate challenge would be somehow describing "intermediate" objects that an API and its SDK may introduce, such as an API response that "wraps" an object for the whole resource, for example: https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/imagebuilder#GetInfrastructureConfigurationOutput
type GetInfrastructureConfigurationOutput struct { // <- API response type
// The infrastructure configuration object.
InfrastructureConfiguration *types.InfrastructureConfiguration // <- Object for resource model
// The request ID that uniquely identifies this request.
RequestId *string // <- Not needed for Terraform state
// Metadata pertaining to the operation's result.
ResultMetadata middleware.Metadata // <- Not needed for Terraform state
// contains filtered or unexported fields
}
However, this would be a problem for solving later. Am I misunderstanding the proposal?
I'm a little confused about what is being proposed here
Think I was the one who was a little confused 😆
I think the approach you proposed of having an array of associated_external_types
sounds good. I think we'll need to be able to identify input/output, so perhaps we'll need a map that identifies request and response:
"associated_external_types": {
"request": {
"import": {
"alias": "...",
"path": "github.com/aws/aws-sdk-go/service/imagebuilder"
},
"type": "*imagebuilder.ImageTestsConfiguration",
"mapping": {
"timeout_minutes": {
"name": "MinutesTimeout"
}
}
},
"response": {
"import": {
"alias": "...",
"path": "github.com/aws/aws-sdk-go/service/imagebuilder"
},
"type": "*imagebuilder.SomethingElse",
"mapping": {
"timeout_minutes": {
"name": "MinutesTimeoutReturnedVal"
}
}
}
}
Alternatively we could have an array with an additional field, perhaps request_response
as an optional enum field, maybe something like:
"associated_external_types": [
{
"request_response": "request",
"import": {
"path": "github.com/aws/aws-sdk-go/service/imagebuilder"
},
"type": "*imagebuilder.ImageTestsConfiguration",
"mapping": {
"timeout_minutes": {
"name": "MinutesTimeout"
}
}
},
{
"request_response": "response",
"import": {
"path": "github.com/aws/aws-sdk-go/service/imagebuilder"
},
"type": "*imagebuilder.SomethingElse",
"mapping": {
"timeout_minutes": {
"name": "MinutesTimeoutReturnedVal"
}
}
}
]
My 🌶️ take is that the associated_external_types specification should not be concerned with API operations at all, only the the linkage of API SDK type to Terraform Schema type. As we get closer to supporting API operations, I think that configuration/specification would handle what an API operation request/response needs in terms of data handling and linking to the schema. There are plenty of cases where an API create operation request might not use "wrapping", but the create/update operation response might. I've also seen APIs where the update operation request can also have "wrapping" of sorts (sorry don't have an example off top of head handy). I would encourage shying away from a shared request/response delineation, because ultimately it might be different per API operation.
Background
Currently,
associated_external_type
is structured as follows:The generation of "expand" and "flatten" methods by _terraform_codegenframework will need to make assumptions about how to map from/to the model struct fields to the
associated_external_type.type
, and in the first instance would use a direct one-to-one mapping. For example, if a resource schema looked as follows:Using an assumed one-to-one mapping for
associated_external_type.type
would yield the following "expand" and "flatten" functions:"expand"
"flatten"
There are assumptions made in this mapping, including but not limited to:
types.Bool
<=> `bool`).Proposal
To provide additional flexibility in the mapping to/from models to API objects defined through
associated_external_type
we should consider the introduction of a "mapping" field, or some other representation, that can be used to shape how the "expand" and "flatten" functions are constructed within _terraform_codegenframework. For instance, we could allow the defining ofrequest
andresponse
fields for eachassociated_external_type
:This contrived example would yield the following "expand" and "flatten" functions:
"expand"
"flatten"