Go RestAPI and DynamoDB with Post/Get/Put/Delete example code

Go with DynamoDB for Post: saving data

Here’s an example of a Go REST API that can handle a POST request to insert data into a DynamoDB table:

package main

import (
    "context"
    "encoding/json"
    "github.com/aws/aws-lambda-go/events"
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/dynamodb"
    "github.com/aws/aws-lambda-go/lambda"
    "github.com/aws/aws-lambda-go/lambdacontext"
    "fmt"
)

type Item struct {
    ID    string `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

func HandleRequest(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
    // Create a new AWS session
    sess := session.Must(session.NewSession())

    // Create a new DynamoDB client
    db := dynamodb.New(sess)

    // Get the request body
    var item Item
    json.Unmarshal([]byte(request.Body), &item)
    if item.ID == "" || item.Name == "" || item.Email == "" {
        return events.APIGatewayProxyResponse{
            Body:       "Missing required fields",
            StatusCode: 400,
        }, nil
    }

    // Create a new DynamoDB PutItemInput
    input := &dynamodb.PutItemInput{
        TableName: aws.String("my-table"),
        Item: map[string]*dynamodb.AttributeValue{
            "id": {
                S: aws.String(item.ID),
            },
            "name": {
                S: aws.String(item.Name),
            },
            "email": {
                S: aws.String(item.Email),
            },
        },
    }

    // Put the item into the DynamoDB table
    _, err := db.PutItem(input)
    if err != nil {
        return events.APIGatewayProxyResponse{
            Body:       fmt.Sprintf("Failed to insert item into DynamoDB: %s", err),
            StatusCode: 500,
        }, nil
    }

    return events.APIGatewayProxyResponse{
        Body:       fmt.Sprintf("Item inserted into DynamoDB"),
        StatusCode: 200,
    }, nil
}

func main() {
    lambda.Start(HandleRequest)
}

In this example, the HandleRequest function is the entry point for the Lambda function, and it takes two parameters: a context.Context and an events.APIGatewayProxyRequest. The function unmarshals the request body into an Item struct, which includes id, name, email fields. The function also checks if any of the fields is missing, if any of the field is missing it returns a Bad Request error message.

Go RestAPI to PUT data to DynamoDB example code

Here’s an example of a Go REST API that can handle a PUT request to update data in a DynamoDB table:

package main

import (
    "context"
    "encoding/json"
    "github.com/aws/aws-lambda-go/events"
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/dynamodb"
    "github.com/aws/aws-lambda-go/lambda"
    "fmt"
)

type Item struct {
    ID    string `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

func HandleRequest(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
    // Create a new AWS session
    sess := session.Must(session.NewSession())

    // Create a new DynamoDB client
    db := dynamodb.New(sess)

    // Get the request body
    var item Item
    json.Unmarshal([]byte(request.Body), &item)
    if item.ID == "" || item.Name == "" || item.Email == "" {
        return events.APIGatewayProxyResponse{
            Body:       "Missing required fields",
            StatusCode: 400,
        }, nil
    }

    // Create a new DynamoDB UpdateItemInput
    input := &dynamodb.UpdateItemInput{
        TableName: aws.String("my-table"),
        Key: map[string]*dynamodb.AttributeValue{
            "id": {
                S: aws.String(item.ID),
            },
        },
        ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
            ":name": {
                S: aws.String(item.Name),
            },
            ":email": {
                S: aws.String(item.Email),
            },
        },
        UpdateExpression: aws.String("SET name = :name, email = :email"),
        ReturnValues:     aws.String("UPDATED_NEW"),
    }

    // Update the item in the DynamoDB table
    _, err := db.UpdateItem(input)
    if err != nil {
        return events.APIGatewayProxyResponse{
            Body:       fmt.Sprintf("Failed to update item in DynamoDB: %s", err),
            StatusCode: 500,
        }, nil
    }

    return events.APIGatewayProxyResponse{
        Body:       fmt.Sprintf("Item updated in DynamoDB"),
        StatusCode: 200,
    }, nil
}

func main() {
    lambda.Start(HandleRequest)
}

In this example, the HandleRequest function is the entry point for the Lambda function, and it takes two parameters: a context.Context and an events.APIGatewayProxyRequest. The function unmarshals the request body into an Item struct, which includes id, name, email fields.

Go RestAPI to Get data from DynamoDB example code

Here is an example of a Go REST API that retrieves data from a DynamoDB table:

package main

import (
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/dynamodb"
    "github.com/gorilla/mux"
    "log"
    "net/http"
)

func main() {
    // Initialize a session that the SDK will use to load
    // credentials from the shared credentials file ~/.aws/credentials
    // and region from the shared configuration file ~/.aws/config.
    sess := session.Must(session.NewSessionWithOptions(session.Options{
        SharedConfigState: session.SharedConfigEnable,
    }))

    // Create DynamoDB client
    svc := dynamodb.New(sess)

    // Create Router
    router := mux.NewRouter()

    // Define API endpoint
    router.HandleFunc("/items/{id}", func(w http.ResponseWriter, r *http.Request) {
        // Get item ID from request parameters
        vars := mux.Vars(r)
        id := vars["id"]

        // Prepare the input for the GetItem function call
        input := &dynamodb.GetItemInput{
            TableName: aws.String("myTable"),
            Key: map[string]*dynamodb.AttributeValue{
                "id": {
                    S: aws.String(id),
                },
            },
        }

        // Call GetItem
        result, err := svc.GetItem(input)
        if err != nil {
            log.Println(err.Error())
            return
        }

        // Write response
        w.Header().Set("Content-Type", "application/json")
        w.Write([]byte(result.String()))
    }).Methods("GET")

    // Start Server
    log.Fatal(http.ListenAndServe(":8000", router))
}

This example uses the Gorilla mux router to handle HTTP requests and the AWS SDK for Go to interact with DynamoDB. The code defines an API endpoint that can be accessed at the path “/items/{id}” and listens on port 8000. When a GET request is received at this endpoint, the code retrieves the item ID from the request parameters, prepares an input for the DynamoDB GetItem function, and calls the function to retrieve the item with the specified ID. The item’s contents are returned in the response.

Note: you need to set up your AWS credentials in the same way as you would for any other AWS SDK that you use.

You can also use the Amazon DynamoDB Document Client, an abstraction over the low-level DynamoDB client that simplifies working with data in DynamoDB. You can find more information on the AWS documentation website.

Go RestAPI to Delete data from DynamoDB example code

Here is an example of a Go REST API that deletes data from a DynamoDB table:

package main

import (
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/dynamodb"
    "github.com/gorilla/mux"
    "log"
    "net/http"
)

func main() {
    // Initialize a session that the SDK will use to load
    // credentials from the shared credentials file ~/.aws/credentials
    // and region from the shared configuration file ~/.aws/config.
    sess := session.Must(session.NewSessionWithOptions(session.Options{
        SharedConfigState: session.SharedConfigEnable,
    }))

    // Create DynamoDB client
    svc := dynamodb.New(sess)

    // Create Router
    router := mux.NewRouter()

    // Define API endpoint
    router.HandleFunc("/items/{id}", func(w http.ResponseWriter, r *http.Request) {
        // Get item ID from request parameters
        vars := mux.Vars(r)
        id := vars["id"]

        // Prepare the input for the DeleteItem function call
        input := &dynamodb.DeleteItemInput{
            TableName: aws.String("myTable"),
            Key: map[string]*dynamodb.AttributeValue{
                "id": {
                    S: aws.String(id),
                },
            },
        }

        // Call DeleteItem
        _, err := svc.DeleteItem(input)
        if err != nil {
            log.Println(err.Error())
            w.WriteHeader(http.StatusInternalServerError)
            return
        }

        // Return success status
        w.WriteHeader(http.StatusOK)
    }).Methods("DELETE")

    // Start Server
    log.Fatal(http.ListenAndServe(":8000", router))
}

This example uses the Gorilla mux router to handle HTTP requests and the AWS SDK for Go to interact with DynamoDB. The code defines an API endpoint that can be accessed at the path “/items/{id}” and listens on port 8000. When a DELETE request is received at this endpoint, the code retrieves the item ID from the request parameters, prepares an input for the DynamoDB DeleteItem function, and calls the function to delete the item with the specified ID. If the delete is successful, the code returns a 200 OK status, otherwise it returns a 500 Internal Server Error status.

Just like the previous example, you need to set up your AWS credentials in the same way as you would for any other AWS SDK that you use.