Interfaces

Intro

GO ist quite strict with type checking. An interfaceis 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:

S3 Event

{  
"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"`
}

Simple: String EventVersion

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",
	}]
}

Complex: userIdentity

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.

Lightly typed

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 also

Source

See the full source on github.

Sources