Skip to content

Instantly share code, notes, and snippets.

@suzuken
Created May 24, 2015 02:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save suzuken/0a7f64a6016b3edfe2c4 to your computer and use it in GitHub Desktop.
Save suzuken/0a7f64a6016b3edfe2c4 to your computer and use it in GitHub Desktop.

autoscale: true

AWS SDK for Go

JAWS-UG Meguro #0

@suzu_v


アジェンダ

  • AWS SDK for Goの紹介
  • 内部での実装の工夫について

オフィシャルな AWS SDK いろいろ

Android, Browser (JavaScript), iOS, Java, .NET, Node.js, PHP, Python, Ruby ...

and Go (Preview 2015/01/29, Unstable): ~

inline


既存のGo実装 (コミュニティ版)

私はこれらのどれも使ったことがありません。使ってる方いたら教えて下さい。


AWS SDK for Go

https://github.com/awslabs/aws-sdk-go

inline


AWS SDK for Go


だいたいこんな感じで使えます

package main

import (
	"fmt"
	"github.com/awslabs/aws-sdk-go/aws"
	"github.com/awslabs/aws-sdk-go/service/s3"
)

// AWS SDK for GoでのListBucketsのサンプル
func main() {
	// credentials are automatically loaded from ~/.aws/credentials
	s := s3.New(&aws.Config{Region: "ap-northeast-1"})

	buckets, _ := s.ListBuckets(nil)

	for _, b := range buckets.Buckets {
		v := *b.Name
		fmt.Printf("bucket: %s\n", v)
	}
}

使ってみた

S3にobjectをputで配置して、list, head, copy, deleteする

aws-sdk-go-example/s3_misc.go at master : suzuken/aws-sdk-go-example


感触

  • わりと書ける、がまだ基礎的なレベルのapiを直接叩く必要がある
  • けれども、Exampleや型によるサポートを利用すると多少楽にかける
    • Exampleも自動生成されている(後述
  • この感触は正式リリース時に変わる可能性があります(Unstable

サポート予定と思われるサービス

autoscaling       dynamodb          rds
cloudformation    ec2               redshift
cloudfront        ecs               route53
cloudhsm          elasticache       route53domains
cloudsearch       elasticbeanstalk  s3
cloudsearchdomain elastictranscoder ses
cloudtrail        elb               simpledb
cloudwatch        emr               sns
cloudwatchlogs    glacier           sqs
codedeploy        iam               ssm
cognitoidentity   importexport      storagegateway
cognitosync       kinesis           sts
configservice     kms               support
datapipeline      lambda            swf
directconnect     opsworks

どのように各種サービスをサポートしているか?


AWS SDK for Go internal

  • /service 以下は モデルベースのapi生成 によって自動生成されたコード
  • /apis/{service_name} にJSONで書かれたapiの定義があり、これを利用している
    • ちなみにこの定義はbotoで使っているものらしい

go generate

Generating code - The Go Blog

  • ライブラリ開発者のための機能
  • ファイルのヘッダに go:generate gen などと書いておくと go generategen が実行される
  • gen を実行することでファイルが生成される
    • ワンライナー実行のためのwrapper

AWS SDK for Go の Makefileより

aws-sdk-go/Makefile at master : awslabs/aws-sdk-go

default: generate

generate-protocol-test:
	go generate ./internal/protocol/...

generate-integration-test:
	go generate ./internal/fixtures/integration

generate-test: generate-protocol-test generate-integration-test

generate:
	go generate ./aws
	go generate ./service

test: generate-test
	go test ./... -tags=integration

ライブラリのコードを生成する

aws-sdk-go/generate.go at master : awslabs/aws-sdk-go

// Package service contains automatically generated AWS clients.
package service

//go:generate go run ../internal/model/cli/gen-api/main.go -path=../service ../apis/*/*.normal.json

internal/model/api あたりを読むとどのようにコードを生成しているかがわかります。


例: ListBuckets (apis/s3 での定義)

それぞれのapiの定義がJSONで書かれている

"ListBuckets":{
  "name":"ListBuckets",
  "http":{
	"method":"GET",
	"requestUri":"/"
  },
  "output":{"shape":"ListBucketsOutput"},
  "documentation":"Returns a list of all buckets owned by the authenticated sender of the request.",
  "documentationUrl":"http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTServiceGET.html",
  "alias":"GetService"
},

https://github.com/awslabs/aws-sdk-go/blob/master/apis/s3/2006-03-01.normal.json#L397-L407


生成されたListBucketsのコード

// ListBucketsRequest generates a request for the ListBuckets operation.
func (c *S3) ListBucketsRequest(input *ListBucketsInput) (req *aws.Request, output *ListBucketsOutput) {
	oprw.Lock()
	defer oprw.Unlock()

	if opListBuckets == nil {
		opListBuckets = &aws.Operation{
			Name:       "ListBuckets",
			HTTPMethod: "GET",
			HTTPPath:   "/",
		}
	}

	if input == nil {
		input = &ListBucketsInput{}
	}

	req = c.newRequest(opListBuckets, input, output)
	output = &ListBucketsOutput{}
	req.Data = output
	return
}

https://github.com/awslabs/aws-sdk-go/blob/master/service/s3/api.go#L1024-L1045


auto-generated example code

  • GoにはExampleがテストになる機能が標準ライブラリに付いている
  • AWS SDK for GoではこのExampleテストも自動生成されている
    • godoc で簡単に実行例をみることができる

Example Test: S3 ListBuckets()の例

func ExampleS3_ListBuckets() {
	svc := s3.New(nil)

	var params *s3.ListBucketsInput
	resp, err := svc.ListBuckets(params)

	if awsErr, ok := err.(awserr.Error); ok {
		// Generic AWS Error with Code, Message, and original error (if any)
		fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr())
		if reqErr, ok := err.(awserr.RequestFailure); ok {
			// A service error occurred
			fmt.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID())
		}
	} else {
		fmt.Println(err.Error())
	}

	// Pretty-print the response data.
	fmt.Println(awsutil.StringValue(resp))
}

aws-sdk-go/examples_test.go at master : awslabs/aws-sdk-go より これも自動生成されている


Godocから見ることができます

http://godoc.org/github.com/awslabs/aws-sdk-go/service/s3#ex-S3-ListBuckets

inline


まとめ

  • AWS SDK for Goはまだ開発中ですが、触れます
  • モデルベースのコード生成が活用されている
    • ExampleやTestも自動生成されている
  • どんどんつかってフィードバックしましょう
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment