Convert JSON to Struct

  1 package main
  2
  3 import (
  4         "encoding/json"
  5         "fmt"
  6         "os"
  7         "github.com/aws/aws-lambda-go/events"
  8 )
  9
 10 func main() {
 11         var event events.S3Event
 12         data, err := os.ReadFile("s3event.json")
 13         if err != nil {
 14                 fmt.Println("Cant read input testdata: ", err)
 15         }
 16         json.Unmarshal(data, &event)
 17
 18         fmt.Println(event.Records[0].S3.Bucket.Name)
 19         fmt.Println(event.Records[0].S3.Object.Key)
 20 }
package main

import (
        "encoding/json"
        "fmt"
        "os"
        "github.com/aws/aws-lambda-go/events"
)

func main() {
        var event events.S3Event
        data, err := os.ReadFile("s3event.json")
        if err != nil {
                fmt.Println("Cant read input testdata: ", err)
        }
        json.Unmarshal(data, &event)

        fmt.Println(event.Records[0].S3.Bucket.Name)
        fmt.Println(event.Records[0].S3.Object.Key)
}
{
  "Records": [
    {
      "eventVersion": "2.1",
      "eventSource": "aws:s3",
      "awsRegion": "us-east-2",
      "eventTime": "2019-09-03T19:37:27.192Z",
      "eventName": "ObjectCreated:Put",
      "userIdentity": {
        "principalId": "AWS:AIDAINPONIXQXHT3IKHL2"
      },
      "requestParameters": {
        "sourceIPAddress": "205.255.255.255"
      },
      "responseElements": {
        "x-amz-request-id": "D82B88E5F771F645",
        "x-amz-id-2": "vlR7PnpV2Ce81l0PRw6jlUpck7Jo5ZsQjryTjKlc5aLWGVHPZLj5NeC6qMa0emYBDXOo6QBU0Wo="
      },
      "s3": {
        "s3SchemaVersion": "1.0",
        "configurationId": "828aa6fc-f7b5-4305-8584-487c791949c1",
        "bucket": {
          "name": "lambda-artifacts-deafc19498e3f2df",
          "ownerIdentity": {
            "principalId": "A3I5XTEXAMAI3E"
          },
          "arn": "arn:aws:s3:::lambda-artifacts-deafc19498e3f2df"
        },
        "object": {
          "key": "b21b84d653bb07b05b1e6b33684dc11b",
          "size": 1305107,
          "eTag": "b21b84d653bb07b05b1e6b33684dc11b",
          "sequencer": "0C0F6F405D6ED209E1"
        }
      }
    }
  ]
}

The process to transform json data into a structure is called marshaling. It is defined in the json library.

You have three steps:

  1. Define a variable in the target structure
  2. Get data (read file)
  3. call unmarshal with a pointer from 1. and the data from 2.

1. Define a variable in the target structure

All structures from AWS events are defined in the aws-lambda-go repository.

The S3Event is an array of S3EventRecord. In the definition there is a tag which tells the json library the name of this record in the json file.

type S3Event struct {
	Records []S3EventRecord `json:"Records"`
}
  1 {
  2   "Records": [
  3     {
  4       "eventVersion": "2.1",

In line 4 you see the JSON array named Records.

The S3EventRecord itself is defined:

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"`
	RequestParameters S3RequestParameters `json:"requestParameters"`
	ResponseElements  map[string]string   `json:"responseElements"`
	S3                S3Entity            `json:"s3"`
}

With this definition it is possible in VSCode (or other editors) to preview the structure:

S3 event preview

Primitive data types

You see primitive data types like

	EventVersion      string              `json:"eventVersion"`

Which matches directly to the line 4:

  1 {
  2   "Records": [
  3     {
  4       "eventVersion": "2.1",

Complex Data Structures

type S3Entity struct {
	SchemaVersion   string   `json:"s3SchemaVersion"`
	ConfigurationID string   `json:"configurationId"`
	Bucket          S3Bucket `json:"bucket"`
	Object          S3Object `json:"object"`
}

This is the complete S3 object in this JSON file:

 19       "s3": {
 20         "s3SchemaVersion": "1.0",
 21         "configurationId": "828aa6fc-f7b5-4305-8584-487c791949c1",
 22         "bucket": {
 23           "name": "lambda-artifacts-deafc19498e3f2df",
 24           "ownerIdentity": {
 25             "principalId": "A3I5XTEXAMAI3E"
 26           },
 27           "arn": "arn:aws:s3:::lambda-artifacts-deafc19498e3f2df"
 28         },

You see the matchings parts from the tags like

   SchemaVersion   string   `json:"s3SchemaVersion"`

to

 20         "s3SchemaVersion": "1.0",

2. Get data (read file)

This is the easy part:

 12         data, err := os.ReadFile("s3event.json")

3. Call unmarshal

This goes through all trees of the json object tree and creates a struct out of it. After this call the json data is available in the event variable and can be used.

 16         json.Unmarshal(data, &event)

See also

Source

See the full source on github.

Sources