SlideShare a Scribd company logo
How to build SDKs in Go
Lessons from the
Go SDK for Dropbox
Diwaker Gupta
● Infrastructure @
Dropbox
● Metadata Services,
Multihoming, Search,
Messaging, Email,
Notifications, Machine
Learning etc
● Authored Dropbox Go
SDK and dbxcli
● Twitter/Github:
@diwakergupta
users businesses
● Gophercon ‘17 Keynote by @tammybutow:
https://bit.ly/gophercon17dbx
● Dozens of Go services, many with millions of RPS!
● We open source at: https://github.com/dropbox
● We are hiring! dropbox.com/jobs or email me (diwaker@)
Lessons from the Dropbox Go SDK
#1: Use a Code Generator
#1: Use a code generator
● Language-agnostic API definition (DSL, JSON,
YAML, etc), Language-specific generators
● Dropbox Stone (spec + generators)
○ https://github.com/dropbox/stone
● Google
○ JSON Spec https://developers.google.com/discovery/
○ Codegen
https://github.com/google/google-api-go-client/
● AWS Go SDK has a very similar setup
● OpenAPI: https://github.com/OAI/OpenAPI-Specification
#2: Avoid Surprises
#2: Avoid Surprises
● Principle of Least Surprise
● No external dependencies
○ Only standard library imports
● No vendored dependencies
● What you need is what you get
○ Scoped sub-packages for larger APIs (e.g. AWS)
○ Make it `go get` friendly
#3: Make Configuration Simple
#3: Make Configuration Simple
● Don’t use cmdline flags
○ Stdlib limitations
● Environment variables
○ OK, but beware pitfalls
● Use a config struct
○ Same pattern in AWS SDK
● Persistence outside SDK
○ Let applications choose
○ dbxcli load/stores json
configs
// Config contains parameters for
configuring the SDK.
type Config struct {
// OAuth2 access token
Token string
// Enable verbose logging in SDK
Verbose bool
...
// For testing only
Client *http.Client
}
#4: Provide Visibility
#4: Provide Visibility
● Allow verbose logging
● Allow configurable
logging targets
● Limited by stdlib :(
type Config struct {
// Enable verbose logging
Verbose bool
// Optional logging target
Logger *log.Logger
}
// TryLog will, if Verbose is set, log to
// the config's logger or the default logger
// if Config.Logger is nil.
func (c *Config) TryLog(format string, v
...interface{}) {
if !c.Verbose {
return
}
if c.Logger != nil {
c.Logger.Printf(format, v...)
} else {
log.Printf(format, v...)
}
}
#5: Use Go idioms for unsupported types
#5: Unions
Consider (in Stone):
union DeleteError
path_lookup LookupError
path_write WriteError
In JSON (note LookupError):
{
".tag": "path_lookup",
"path_lookup": {
".tag": "malformed_path",
"malformed_path": "/some/path"
}
}
Equivalent struct in Go
type DeleteError struct {
dropbox.Tagged
PathLookup *LookupError `json:"path_lookup"`
PathWrite *WriteError `json:"path_write"`
}
Problem: (de)serialization
func (u *DeleteError) UnmarshalJSON(body []byte)
error {
type wrap struct {
dropbox.Tagged
PathLookup json.RawMessage
PathWrite json.RawMessage
}
var w wrap
switch w.Tag {
case "path_lookup":
err = json.Unmarshal(w.PathLookup,
&u.PathLookup)
...
case "path_write":
err = json.Unmarshal(w.PathWrite,
&u.PathWrite)
...
}
#5: Unions
type DeleteError struct {
dropbox.Tagged
PathLookup *LookupError
`json:"path_lookup,omitempty"`
PathWrite *WriteError
`json:"path_write,omitempty"`
}
{
".tag": "path_lookup",
"path_lookup": {
".tag": "malformed_path",
"malformed_path": "/some/path"
}
}
#5: Inherited Types
In Stone
struct Metadata
// Common fields: Name, Path etc
union
file FileMetadata
folder FolderMetadata
Idiomatic Go: Embedding
type Metadata struct {
// Common fields
}
type FileMetadata struct {
Metadata
// FileMetadata specific fields
}
type FolderMetadata struct {
Metadata
// FolderMetadata specific fields
}
Solution: Use a dummy interface
type IsMetadata interface {
IsMetadata()
}
// Subtypes get this via embedding
func (u *Metadata) IsMetadata() {}
// Use IsMetadata where you need
// the union type
#5: Inherited Types
Problem: Polymorphism
func List(...) []Metadata
Can return FileMetadata or
FolderMetadata
Similar trick as Unions
type metadataUnion struct {
dropbox.Tagged
File *FileMetadata
Folder *FolderMetadata
}
func IsMetadataFromJSON(data []byte) (IsMetadata,
e) {
var t metadataUnion
if err := json.Unmarshal(data, &t); err !=
nil {
return nil, err
}
switch t.Tag {
...
}
}
#5: Inherited Types
Problem: (de)serialization
{
".tag": "file",
"name": "Prime_Numbers.txt",
"id": "id:a4ayc_80_OEAAAAAAAAAXw",
"content_hash": "e3b0c44298fc"
}
OR
{
".tag": "folder",
"name": "math",
"id": "id:a4ayc_80_OEAAAAAAAAAXz",
"path_lower": "/homework/math",
}
#6: Do NOT authenticate
#6: Do NOT authenticate
● Apps authenticate, SDK accepts OAuth Token
● Beware of known OAuth pitfalls
○ Changed OAuth Endpoint from api.dropbox.com to
api.dropboxapi.com
○ App started failing with oauth2: cannot fetch token:
400 Bad Request
○ Gem from oauth2/internal/token.go
○ func RegisterBrokenAuthHeaderProvider(tokenURL string)
○ Google, Stripe and yes, Dropbox are “broken”
● More information:
○ On debugging OAuth2 in #golang
#7: Auto Generate Tests
#7: Auto Generate Tests
● Tests should be
comprehensive and
up-to-date
● Dropbox SDK is NOT a
good example!
● Model after AWS SDK
○ Example input/output
defined in JSON
○ Tests are auto-generated
● Not a panacea, still
need to write tests!
○ Especially negative tests
#8: Handle errors the Go way
#8: Handle errors the Go way
Dropbox SDK
res, err := dbx.ListFolder(arg)
if err != nil {
switch e := err.(type) {
case files.ListFolderAPIError:
...
AWS SDK
output, err := s3manage.Upload(...)
if err != nil {
if reqerr, ok := err.(RequestFailure);
ok {
...
● Have SDK errors implement the `error` interface
● Use type assertions to extract errors
● Good packages exist for combining / unrolling errors --
wish stdlib had more support!
Lessons Recap
1. Use a Code Generator
2. Avoid Surprises
3. Make Configuration Simple
4. Provide Visibility
5. Use Go Idioms for Unsupported Types
6. Do Not Authenticate
7. Auto Generate Tests
8. Handle Errors the Go Way
Where to get it?
● SDK:https://github.com/dropbox/dropbox-sdk-go-unofficial
● dbxcli: https://github.com/dropbox/dbxcli/
○ Command line tool for Dropbox
○ Pre-compiled binaries for Windows, Mac, Linux, ARM
○ Useful for end users as well as team administrators
● Support for Dropbox Paper coming soon!
○ https://www.dropbox.com/paper
How to build SDKs in Go
How to build SDKs in Go
Ad

More Related Content

What's hot (20)

Web development
Web developmentWeb development
Web development
GarvitBaleshwar
 
CPanel User Guide
CPanel User GuideCPanel User Guide
CPanel User Guide
webhostingguy
 
Metadata is a Love Note to the Future
Metadata is a Love Note to the FutureMetadata is a Love Note to the Future
Metadata is a Love Note to the Future
Rachel Lovinger
 
AEM Sightly Template Language
AEM Sightly Template LanguageAEM Sightly Template Language
AEM Sightly Template Language
Gabriel Walt
 
Mongoose and MongoDB 101
Mongoose and MongoDB 101Mongoose and MongoDB 101
Mongoose and MongoDB 101
Will Button
 
Java script - funções
Java script - funçõesJava script - funções
Java script - funções
Cristiano Pires Martins
 
Deals made easy| Online Shopping Kart |Java,Jsp,JDBC
Deals made easy| Online Shopping Kart |Java,Jsp,JDBCDeals made easy| Online Shopping Kart |Java,Jsp,JDBC
Deals made easy| Online Shopping Kart |Java,Jsp,JDBC
SaikiranReddy Sama
 
Experience and Content Fragment
Experience and Content FragmentExperience and Content Fragment
Experience and Content Fragment
Heena Madan
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
Ahmed Salama
 
Front end-developer
Front end-developerFront end-developer
Front end-developer
qaskhk
 
Introdução a Bootstrap 3
Introdução a Bootstrap 3Introdução a Bootstrap 3
Introdução a Bootstrap 3
Iago Effting
 
Grafana Loki: like Prometheus, but for Logs
Grafana Loki: like Prometheus, but for LogsGrafana Loki: like Prometheus, but for Logs
Grafana Loki: like Prometheus, but for Logs
Marco Pracucci
 
HashiCorp's Vault - The Examples
HashiCorp's Vault - The ExamplesHashiCorp's Vault - The Examples
HashiCorp's Vault - The Examples
Michał Czeraszkiewicz
 
REST in Peace
REST in PeaceREST in Peace
REST in Peace
Kate Marshalkina
 
Web scraping with BeautifulSoup, LXML, RegEx and Scrapy
Web scraping with BeautifulSoup, LXML, RegEx and ScrapyWeb scraping with BeautifulSoup, LXML, RegEx and Scrapy
Web scraping with BeautifulSoup, LXML, RegEx and Scrapy
LITTINRAJAN
 
Online shopping ecommerce java project
Online shopping ecommerce java projectOnline shopping ecommerce java project
Online shopping ecommerce java project
Tutorial Learners
 
Html & CSS - Best practices 2-hour-workshop
Html & CSS - Best practices 2-hour-workshopHtml & CSS - Best practices 2-hour-workshop
Html & CSS - Best practices 2-hour-workshop
Vero Rebagliatte
 
Bootstrap 5 whats new
Bootstrap 5   whats newBootstrap 5   whats new
Bootstrap 5 whats new
Sandun Perera
 
Understanding Sling Models in AEM
Understanding Sling Models in AEMUnderstanding Sling Models in AEM
Understanding Sling Models in AEM
Accunity Software
 
Using cookies and sessions
Using cookies and sessionsUsing cookies and sessions
Using cookies and sessions
Nuha Noor
 
Metadata is a Love Note to the Future
Metadata is a Love Note to the FutureMetadata is a Love Note to the Future
Metadata is a Love Note to the Future
Rachel Lovinger
 
AEM Sightly Template Language
AEM Sightly Template LanguageAEM Sightly Template Language
AEM Sightly Template Language
Gabriel Walt
 
Mongoose and MongoDB 101
Mongoose and MongoDB 101Mongoose and MongoDB 101
Mongoose and MongoDB 101
Will Button
 
Deals made easy| Online Shopping Kart |Java,Jsp,JDBC
Deals made easy| Online Shopping Kart |Java,Jsp,JDBCDeals made easy| Online Shopping Kart |Java,Jsp,JDBC
Deals made easy| Online Shopping Kart |Java,Jsp,JDBC
SaikiranReddy Sama
 
Experience and Content Fragment
Experience and Content FragmentExperience and Content Fragment
Experience and Content Fragment
Heena Madan
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
Ahmed Salama
 
Front end-developer
Front end-developerFront end-developer
Front end-developer
qaskhk
 
Introdução a Bootstrap 3
Introdução a Bootstrap 3Introdução a Bootstrap 3
Introdução a Bootstrap 3
Iago Effting
 
Grafana Loki: like Prometheus, but for Logs
Grafana Loki: like Prometheus, but for LogsGrafana Loki: like Prometheus, but for Logs
Grafana Loki: like Prometheus, but for Logs
Marco Pracucci
 
Web scraping with BeautifulSoup, LXML, RegEx and Scrapy
Web scraping with BeautifulSoup, LXML, RegEx and ScrapyWeb scraping with BeautifulSoup, LXML, RegEx and Scrapy
Web scraping with BeautifulSoup, LXML, RegEx and Scrapy
LITTINRAJAN
 
Online shopping ecommerce java project
Online shopping ecommerce java projectOnline shopping ecommerce java project
Online shopping ecommerce java project
Tutorial Learners
 
Html & CSS - Best practices 2-hour-workshop
Html & CSS - Best practices 2-hour-workshopHtml & CSS - Best practices 2-hour-workshop
Html & CSS - Best practices 2-hour-workshop
Vero Rebagliatte
 
Bootstrap 5 whats new
Bootstrap 5   whats newBootstrap 5   whats new
Bootstrap 5 whats new
Sandun Perera
 
Understanding Sling Models in AEM
Understanding Sling Models in AEMUnderstanding Sling Models in AEM
Understanding Sling Models in AEM
Accunity Software
 
Using cookies and sessions
Using cookies and sessionsUsing cookies and sessions
Using cookies and sessions
Nuha Noor
 

Similar to How to build SDKs in Go (20)

Go 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX GoGo 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX Go
Rodolfo Carvalho
 
Grails Introduction - IJTC 2007
Grails Introduction - IJTC 2007Grails Introduction - IJTC 2007
Grails Introduction - IJTC 2007
Guillaume Laforge
 
"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson
GWTcon
 
Getting started with go - Florin Patan - Codemotion Milan 2016
Getting started with go - Florin Patan - Codemotion Milan 2016Getting started with go - Florin Patan - Codemotion Milan 2016
Getting started with go - Florin Patan - Codemotion Milan 2016
Codemotion
 
Grooscript greach
Grooscript greachGrooscript greach
Grooscript greach
Jorge Franco Leza
 
dojo.Patterns
dojo.Patternsdojo.Patterns
dojo.Patterns
Peter Higgins
 
Mobile Apps by Pure Go with Reverse Binding
Mobile Apps by Pure Go with Reverse BindingMobile Apps by Pure Go with Reverse Binding
Mobile Apps by Pure Go with Reverse Binding
Takuya Ueda
 
Building Dojo in the Cloud
Building Dojo in the CloudBuilding Dojo in the Cloud
Building Dojo in the Cloud
James Thomas
 
JavaOne 2008 - TS-5793 - Groovy and Grails, changing the landscape of Java EE...
JavaOne 2008 - TS-5793 - Groovy and Grails, changing the landscape of Java EE...JavaOne 2008 - TS-5793 - Groovy and Grails, changing the landscape of Java EE...
JavaOne 2008 - TS-5793 - Groovy and Grails, changing the landscape of Java EE...
Guillaume Laforge
 
Build Great Networked APIs with Swift, OpenAPI, and gRPC
Build Great Networked APIs with Swift, OpenAPI, and gRPCBuild Great Networked APIs with Swift, OpenAPI, and gRPC
Build Great Networked APIs with Swift, OpenAPI, and gRPC
Tim Burks
 
Grooscript gr8conf 2015
Grooscript gr8conf 2015Grooscript gr8conf 2015
Grooscript gr8conf 2015
Jorge Franco Leza
 
Go, meet Lua
Go, meet LuaGo, meet Lua
Go, meet Lua
Andre Burgaud
 
Missing objects: ?. and ?? in JavaScript (BrazilJS 2018)
Missing objects: ?. and ?? in JavaScript (BrazilJS 2018)Missing objects: ?. and ?? in JavaScript (BrazilJS 2018)
Missing objects: ?. and ?? in JavaScript (BrazilJS 2018)
Igalia
 
Daniel Steigerwald: EsteJS - javascriptové aplikace robusně, modulárně a komf...
Daniel Steigerwald: EsteJS - javascriptové aplikace robusně, modulárně a komf...Daniel Steigerwald: EsteJS - javascriptové aplikace robusně, modulárně a komf...
Daniel Steigerwald: EsteJS - javascriptové aplikace robusně, modulárně a komf...
Develcz
 
Little Did He Know ...
Little Did He Know ...Little Did He Know ...
Little Did He Know ...
Burt Beckwith
 
JavaScript ES6
JavaScript ES6JavaScript ES6
JavaScript ES6
Leo Hernandez
 
Cape Cod Web Technology Meetup - 3
Cape Cod Web Technology Meetup - 3Cape Cod Web Technology Meetup - 3
Cape Cod Web Technology Meetup - 3
Asher Martin
 
PHP BASIC PRESENTATION
PHP BASIC PRESENTATIONPHP BASIC PRESENTATION
PHP BASIC PRESENTATION
krutitrivedi
 
Golang introduction
Golang introductionGolang introduction
Golang introduction
DineshDinesh131
 
SF Grails - Ratpack - Compact Groovy Webapps - James Williams
SF Grails - Ratpack - Compact Groovy Webapps - James WilliamsSF Grails - Ratpack - Compact Groovy Webapps - James Williams
SF Grails - Ratpack - Compact Groovy Webapps - James Williams
Philip Stehlik
 
Go 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX GoGo 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX Go
Rodolfo Carvalho
 
Grails Introduction - IJTC 2007
Grails Introduction - IJTC 2007Grails Introduction - IJTC 2007
Grails Introduction - IJTC 2007
Guillaume Laforge
 
"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson
GWTcon
 
Getting started with go - Florin Patan - Codemotion Milan 2016
Getting started with go - Florin Patan - Codemotion Milan 2016Getting started with go - Florin Patan - Codemotion Milan 2016
Getting started with go - Florin Patan - Codemotion Milan 2016
Codemotion
 
Mobile Apps by Pure Go with Reverse Binding
Mobile Apps by Pure Go with Reverse BindingMobile Apps by Pure Go with Reverse Binding
Mobile Apps by Pure Go with Reverse Binding
Takuya Ueda
 
Building Dojo in the Cloud
Building Dojo in the CloudBuilding Dojo in the Cloud
Building Dojo in the Cloud
James Thomas
 
JavaOne 2008 - TS-5793 - Groovy and Grails, changing the landscape of Java EE...
JavaOne 2008 - TS-5793 - Groovy and Grails, changing the landscape of Java EE...JavaOne 2008 - TS-5793 - Groovy and Grails, changing the landscape of Java EE...
JavaOne 2008 - TS-5793 - Groovy and Grails, changing the landscape of Java EE...
Guillaume Laforge
 
Build Great Networked APIs with Swift, OpenAPI, and gRPC
Build Great Networked APIs with Swift, OpenAPI, and gRPCBuild Great Networked APIs with Swift, OpenAPI, and gRPC
Build Great Networked APIs with Swift, OpenAPI, and gRPC
Tim Burks
 
Missing objects: ?. and ?? in JavaScript (BrazilJS 2018)
Missing objects: ?. and ?? in JavaScript (BrazilJS 2018)Missing objects: ?. and ?? in JavaScript (BrazilJS 2018)
Missing objects: ?. and ?? in JavaScript (BrazilJS 2018)
Igalia
 
Daniel Steigerwald: EsteJS - javascriptové aplikace robusně, modulárně a komf...
Daniel Steigerwald: EsteJS - javascriptové aplikace robusně, modulárně a komf...Daniel Steigerwald: EsteJS - javascriptové aplikace robusně, modulárně a komf...
Daniel Steigerwald: EsteJS - javascriptové aplikace robusně, modulárně a komf...
Develcz
 
Little Did He Know ...
Little Did He Know ...Little Did He Know ...
Little Did He Know ...
Burt Beckwith
 
Cape Cod Web Technology Meetup - 3
Cape Cod Web Technology Meetup - 3Cape Cod Web Technology Meetup - 3
Cape Cod Web Technology Meetup - 3
Asher Martin
 
PHP BASIC PRESENTATION
PHP BASIC PRESENTATIONPHP BASIC PRESENTATION
PHP BASIC PRESENTATION
krutitrivedi
 
SF Grails - Ratpack - Compact Groovy Webapps - James Williams
SF Grails - Ratpack - Compact Groovy Webapps - James WilliamsSF Grails - Ratpack - Compact Groovy Webapps - James Williams
SF Grails - Ratpack - Compact Groovy Webapps - James Williams
Philip Stehlik
 
Ad

Recently uploaded (20)

What Do Contribution Guidelines Say About Software Testing? (MSR 2025)
What Do Contribution Guidelines Say About Software Testing? (MSR 2025)What Do Contribution Guidelines Say About Software Testing? (MSR 2025)
What Do Contribution Guidelines Say About Software Testing? (MSR 2025)
Andre Hora
 
How can one start with crypto wallet development.pptx
How can one start with crypto wallet development.pptxHow can one start with crypto wallet development.pptx
How can one start with crypto wallet development.pptx
laravinson24
 
Douwan Crack 2025 new verson+ License code
Douwan Crack 2025 new verson+ License codeDouwan Crack 2025 new verson+ License code
Douwan Crack 2025 new verson+ License code
aneelaramzan63
 
Who Watches the Watchmen (SciFiDevCon 2025)
Who Watches the Watchmen (SciFiDevCon 2025)Who Watches the Watchmen (SciFiDevCon 2025)
Who Watches the Watchmen (SciFiDevCon 2025)
Allon Mureinik
 
Not So Common Memory Leaks in Java Webinar
Not So Common Memory Leaks in Java WebinarNot So Common Memory Leaks in Java Webinar
Not So Common Memory Leaks in Java Webinar
Tier1 app
 
Salesforce Data Cloud- Hyperscale data platform, built for Salesforce.
Salesforce Data Cloud- Hyperscale data platform, built for Salesforce.Salesforce Data Cloud- Hyperscale data platform, built for Salesforce.
Salesforce Data Cloud- Hyperscale data platform, built for Salesforce.
Dele Amefo
 
LEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRY
LEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRYLEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRY
LEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRY
NidaFarooq10
 
WinRAR Crack for Windows (100% Working 2025)
WinRAR Crack for Windows (100% Working 2025)WinRAR Crack for Windows (100% Working 2025)
WinRAR Crack for Windows (100% Working 2025)
sh607827
 
Why Orangescrum Is a Game Changer for Construction Companies in 2025
Why Orangescrum Is a Game Changer for Construction Companies in 2025Why Orangescrum Is a Game Changer for Construction Companies in 2025
Why Orangescrum Is a Game Changer for Construction Companies in 2025
Orangescrum
 
Scaling GraphRAG: Efficient Knowledge Retrieval for Enterprise AI
Scaling GraphRAG:  Efficient Knowledge Retrieval for Enterprise AIScaling GraphRAG:  Efficient Knowledge Retrieval for Enterprise AI
Scaling GraphRAG: Efficient Knowledge Retrieval for Enterprise AI
danshalev
 
Adobe Marketo Engage Champion Deep Dive - SFDC CRM Synch V2 & Usage Dashboards
Adobe Marketo Engage Champion Deep Dive - SFDC CRM Synch V2 & Usage DashboardsAdobe Marketo Engage Champion Deep Dive - SFDC CRM Synch V2 & Usage Dashboards
Adobe Marketo Engage Champion Deep Dive - SFDC CRM Synch V2 & Usage Dashboards
BradBedford3
 
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Lionel Briand
 
Exploring Code Comprehension in Scientific Programming: Preliminary Insight...
Exploring Code Comprehension  in Scientific Programming:  Preliminary Insight...Exploring Code Comprehension  in Scientific Programming:  Preliminary Insight...
Exploring Code Comprehension in Scientific Programming: Preliminary Insight...
University of Hawai‘i at Mānoa
 
How to Optimize Your AWS Environment for Improved Cloud Performance
How to Optimize Your AWS Environment for Improved Cloud PerformanceHow to Optimize Your AWS Environment for Improved Cloud Performance
How to Optimize Your AWS Environment for Improved Cloud Performance
ThousandEyes
 
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Eric D. Schabell
 
Kubernetes_101_Zero_to_Platform_Engineer.pptx
Kubernetes_101_Zero_to_Platform_Engineer.pptxKubernetes_101_Zero_to_Platform_Engineer.pptx
Kubernetes_101_Zero_to_Platform_Engineer.pptx
CloudScouts
 
Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025
kashifyounis067
 
Get & Download Wondershare Filmora Crack Latest [2025]
Get & Download Wondershare Filmora Crack Latest [2025]Get & Download Wondershare Filmora Crack Latest [2025]
Get & Download Wondershare Filmora Crack Latest [2025]
saniaaftab72555
 
EASEUS Partition Master Crack + License Code
EASEUS Partition Master Crack + License CodeEASEUS Partition Master Crack + License Code
EASEUS Partition Master Crack + License Code
aneelaramzan63
 
Microsoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdf
Microsoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdfMicrosoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdf
Microsoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdf
TechSoup
 
What Do Contribution Guidelines Say About Software Testing? (MSR 2025)
What Do Contribution Guidelines Say About Software Testing? (MSR 2025)What Do Contribution Guidelines Say About Software Testing? (MSR 2025)
What Do Contribution Guidelines Say About Software Testing? (MSR 2025)
Andre Hora
 
How can one start with crypto wallet development.pptx
How can one start with crypto wallet development.pptxHow can one start with crypto wallet development.pptx
How can one start with crypto wallet development.pptx
laravinson24
 
Douwan Crack 2025 new verson+ License code
Douwan Crack 2025 new verson+ License codeDouwan Crack 2025 new verson+ License code
Douwan Crack 2025 new verson+ License code
aneelaramzan63
 
Who Watches the Watchmen (SciFiDevCon 2025)
Who Watches the Watchmen (SciFiDevCon 2025)Who Watches the Watchmen (SciFiDevCon 2025)
Who Watches the Watchmen (SciFiDevCon 2025)
Allon Mureinik
 
Not So Common Memory Leaks in Java Webinar
Not So Common Memory Leaks in Java WebinarNot So Common Memory Leaks in Java Webinar
Not So Common Memory Leaks in Java Webinar
Tier1 app
 
Salesforce Data Cloud- Hyperscale data platform, built for Salesforce.
Salesforce Data Cloud- Hyperscale data platform, built for Salesforce.Salesforce Data Cloud- Hyperscale data platform, built for Salesforce.
Salesforce Data Cloud- Hyperscale data platform, built for Salesforce.
Dele Amefo
 
LEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRY
LEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRYLEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRY
LEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRY
NidaFarooq10
 
WinRAR Crack for Windows (100% Working 2025)
WinRAR Crack for Windows (100% Working 2025)WinRAR Crack for Windows (100% Working 2025)
WinRAR Crack for Windows (100% Working 2025)
sh607827
 
Why Orangescrum Is a Game Changer for Construction Companies in 2025
Why Orangescrum Is a Game Changer for Construction Companies in 2025Why Orangescrum Is a Game Changer for Construction Companies in 2025
Why Orangescrum Is a Game Changer for Construction Companies in 2025
Orangescrum
 
Scaling GraphRAG: Efficient Knowledge Retrieval for Enterprise AI
Scaling GraphRAG:  Efficient Knowledge Retrieval for Enterprise AIScaling GraphRAG:  Efficient Knowledge Retrieval for Enterprise AI
Scaling GraphRAG: Efficient Knowledge Retrieval for Enterprise AI
danshalev
 
Adobe Marketo Engage Champion Deep Dive - SFDC CRM Synch V2 & Usage Dashboards
Adobe Marketo Engage Champion Deep Dive - SFDC CRM Synch V2 & Usage DashboardsAdobe Marketo Engage Champion Deep Dive - SFDC CRM Synch V2 & Usage Dashboards
Adobe Marketo Engage Champion Deep Dive - SFDC CRM Synch V2 & Usage Dashboards
BradBedford3
 
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Lionel Briand
 
Exploring Code Comprehension in Scientific Programming: Preliminary Insight...
Exploring Code Comprehension  in Scientific Programming:  Preliminary Insight...Exploring Code Comprehension  in Scientific Programming:  Preliminary Insight...
Exploring Code Comprehension in Scientific Programming: Preliminary Insight...
University of Hawai‘i at Mānoa
 
How to Optimize Your AWS Environment for Improved Cloud Performance
How to Optimize Your AWS Environment for Improved Cloud PerformanceHow to Optimize Your AWS Environment for Improved Cloud Performance
How to Optimize Your AWS Environment for Improved Cloud Performance
ThousandEyes
 
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Eric D. Schabell
 
Kubernetes_101_Zero_to_Platform_Engineer.pptx
Kubernetes_101_Zero_to_Platform_Engineer.pptxKubernetes_101_Zero_to_Platform_Engineer.pptx
Kubernetes_101_Zero_to_Platform_Engineer.pptx
CloudScouts
 
Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025
kashifyounis067
 
Get & Download Wondershare Filmora Crack Latest [2025]
Get & Download Wondershare Filmora Crack Latest [2025]Get & Download Wondershare Filmora Crack Latest [2025]
Get & Download Wondershare Filmora Crack Latest [2025]
saniaaftab72555
 
EASEUS Partition Master Crack + License Code
EASEUS Partition Master Crack + License CodeEASEUS Partition Master Crack + License Code
EASEUS Partition Master Crack + License Code
aneelaramzan63
 
Microsoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdf
Microsoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdfMicrosoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdf
Microsoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdf
TechSoup
 
Ad

How to build SDKs in Go

  • 1. How to build SDKs in Go Lessons from the Go SDK for Dropbox
  • 2. Diwaker Gupta ● Infrastructure @ Dropbox ● Metadata Services, Multihoming, Search, Messaging, Email, Notifications, Machine Learning etc ● Authored Dropbox Go SDK and dbxcli ● Twitter/Github: @diwakergupta
  • 4. ● Gophercon ‘17 Keynote by @tammybutow: https://bit.ly/gophercon17dbx ● Dozens of Go services, many with millions of RPS! ● We open source at: https://github.com/dropbox ● We are hiring! dropbox.com/jobs or email me (diwaker@)
  • 5. Lessons from the Dropbox Go SDK
  • 6. #1: Use a Code Generator
  • 7. #1: Use a code generator ● Language-agnostic API definition (DSL, JSON, YAML, etc), Language-specific generators ● Dropbox Stone (spec + generators) ○ https://github.com/dropbox/stone ● Google ○ JSON Spec https://developers.google.com/discovery/ ○ Codegen https://github.com/google/google-api-go-client/ ● AWS Go SDK has a very similar setup ● OpenAPI: https://github.com/OAI/OpenAPI-Specification
  • 9. #2: Avoid Surprises ● Principle of Least Surprise ● No external dependencies ○ Only standard library imports ● No vendored dependencies ● What you need is what you get ○ Scoped sub-packages for larger APIs (e.g. AWS) ○ Make it `go get` friendly
  • 11. #3: Make Configuration Simple ● Don’t use cmdline flags ○ Stdlib limitations ● Environment variables ○ OK, but beware pitfalls ● Use a config struct ○ Same pattern in AWS SDK ● Persistence outside SDK ○ Let applications choose ○ dbxcli load/stores json configs // Config contains parameters for configuring the SDK. type Config struct { // OAuth2 access token Token string // Enable verbose logging in SDK Verbose bool ... // For testing only Client *http.Client }
  • 13. #4: Provide Visibility ● Allow verbose logging ● Allow configurable logging targets ● Limited by stdlib :( type Config struct { // Enable verbose logging Verbose bool // Optional logging target Logger *log.Logger } // TryLog will, if Verbose is set, log to // the config's logger or the default logger // if Config.Logger is nil. func (c *Config) TryLog(format string, v ...interface{}) { if !c.Verbose { return } if c.Logger != nil { c.Logger.Printf(format, v...) } else { log.Printf(format, v...) } }
  • 14. #5: Use Go idioms for unsupported types
  • 15. #5: Unions Consider (in Stone): union DeleteError path_lookup LookupError path_write WriteError In JSON (note LookupError): { ".tag": "path_lookup", "path_lookup": { ".tag": "malformed_path", "malformed_path": "/some/path" } } Equivalent struct in Go type DeleteError struct { dropbox.Tagged PathLookup *LookupError `json:"path_lookup"` PathWrite *WriteError `json:"path_write"` } Problem: (de)serialization
  • 16. func (u *DeleteError) UnmarshalJSON(body []byte) error { type wrap struct { dropbox.Tagged PathLookup json.RawMessage PathWrite json.RawMessage } var w wrap switch w.Tag { case "path_lookup": err = json.Unmarshal(w.PathLookup, &u.PathLookup) ... case "path_write": err = json.Unmarshal(w.PathWrite, &u.PathWrite) ... } #5: Unions type DeleteError struct { dropbox.Tagged PathLookup *LookupError `json:"path_lookup,omitempty"` PathWrite *WriteError `json:"path_write,omitempty"` } { ".tag": "path_lookup", "path_lookup": { ".tag": "malformed_path", "malformed_path": "/some/path" } }
  • 17. #5: Inherited Types In Stone struct Metadata // Common fields: Name, Path etc union file FileMetadata folder FolderMetadata Idiomatic Go: Embedding type Metadata struct { // Common fields } type FileMetadata struct { Metadata // FileMetadata specific fields } type FolderMetadata struct { Metadata // FolderMetadata specific fields }
  • 18. Solution: Use a dummy interface type IsMetadata interface { IsMetadata() } // Subtypes get this via embedding func (u *Metadata) IsMetadata() {} // Use IsMetadata where you need // the union type #5: Inherited Types Problem: Polymorphism func List(...) []Metadata Can return FileMetadata or FolderMetadata
  • 19. Similar trick as Unions type metadataUnion struct { dropbox.Tagged File *FileMetadata Folder *FolderMetadata } func IsMetadataFromJSON(data []byte) (IsMetadata, e) { var t metadataUnion if err := json.Unmarshal(data, &t); err != nil { return nil, err } switch t.Tag { ... } } #5: Inherited Types Problem: (de)serialization { ".tag": "file", "name": "Prime_Numbers.txt", "id": "id:a4ayc_80_OEAAAAAAAAAXw", "content_hash": "e3b0c44298fc" } OR { ".tag": "folder", "name": "math", "id": "id:a4ayc_80_OEAAAAAAAAAXz", "path_lower": "/homework/math", }
  • 20. #6: Do NOT authenticate
  • 21. #6: Do NOT authenticate ● Apps authenticate, SDK accepts OAuth Token ● Beware of known OAuth pitfalls ○ Changed OAuth Endpoint from api.dropbox.com to api.dropboxapi.com ○ App started failing with oauth2: cannot fetch token: 400 Bad Request ○ Gem from oauth2/internal/token.go ○ func RegisterBrokenAuthHeaderProvider(tokenURL string) ○ Google, Stripe and yes, Dropbox are “broken” ● More information: ○ On debugging OAuth2 in #golang
  • 23. #7: Auto Generate Tests ● Tests should be comprehensive and up-to-date ● Dropbox SDK is NOT a good example! ● Model after AWS SDK ○ Example input/output defined in JSON ○ Tests are auto-generated ● Not a panacea, still need to write tests! ○ Especially negative tests
  • 24. #8: Handle errors the Go way
  • 25. #8: Handle errors the Go way Dropbox SDK res, err := dbx.ListFolder(arg) if err != nil { switch e := err.(type) { case files.ListFolderAPIError: ... AWS SDK output, err := s3manage.Upload(...) if err != nil { if reqerr, ok := err.(RequestFailure); ok { ... ● Have SDK errors implement the `error` interface ● Use type assertions to extract errors ● Good packages exist for combining / unrolling errors -- wish stdlib had more support!
  • 26. Lessons Recap 1. Use a Code Generator 2. Avoid Surprises 3. Make Configuration Simple 4. Provide Visibility 5. Use Go Idioms for Unsupported Types 6. Do Not Authenticate 7. Auto Generate Tests 8. Handle Errors the Go Way
  • 27. Where to get it? ● SDK:https://github.com/dropbox/dropbox-sdk-go-unofficial ● dbxcli: https://github.com/dropbox/dbxcli/ ○ Command line tool for Dropbox ○ Pre-compiled binaries for Windows, Mac, Linux, ARM ○ Useful for end users as well as team administrators ● Support for Dropbox Paper coming soon! ○ https://www.dropbox.com/paper