GO ist quite strict with type checking. An interface
is the way to reference unknown data. This is often used with json.
So with JSON a map[string]interface{}
is often used.
Lets have a look at the first lines of the AWS S3 event record in JSON:
{
"eventVersion":"2.2",
"eventSource":"aws:s3",
"awsRegion":"us-west-2",
"eventTime":"1970-01-01T00:00:00.000Z",
"eventName":"event-type",
"userIdentity":{
"principalId":"Amazon-customer-ID-of-the-user-who-caused-the-event"
}
}
If we know the structure of the data in advance, you can define all parts, like in https://github.com/aws/aws-lambda-go/blob/main/events/s3.go
We got
type S3EventRecord struct {
EventVersion string `json:"eventVersion"`
EventSource string `json:"eventSource"`
AWSRegion string `json:"awsRegion"`
EventTime time.Time `json:"eventTime"`
EventName string `json:"eventName"`
PrincipalID S3UserIdentity `json:"userIdentity"`
}
type S3UserIdentity struct {
PrincipalID string `json:"principalId"`
}
To fully understand this, we look at the simple structures from the S3EventRecord:
EventVersion string `json:"eventVersion"`
This corresponds to the JSON part:
{
"Records": [
{
"eventVersion": "2.0",
}]
}
The complex structs like
PrincipalID S3UserIdentity `json:"userIdentity"`
Refers to this part in the S3 event json:
{
"Records":[
{
"userIdentity":{
"principalId":"Amazon-customer-ID-of-the-user-who-caused-the-event"
}
}
]
}
Where another struct is referenced. Everything defined, all good. The part
`json:"eventVersion"`
Tells us later that the GO variable EventVersion will be set as eventVersion in JSON. In GO this has to be uppercase, in JSON it can be any case.
But sometimes the json is not fixed.
If you work with Amazon Connect Contact Trace Records, you have ContactDetails, which are “lightly typed”, which means you don’t know in advance, which JSON structure will be there.
In this case, you may define:
ContactDetails interface{} `json:"ContactDetails"`
This way you have the standard Python and node behavior of untyped structs.
See the full source on github.