Slide 1

Slide 1 text

Using Go to Guide
 API Design Decisions dotGo 2016 lightning talk

Slide 2

Slide 2 text

This is Tiny P., our li9le resolver, pretending to be a Gopher.

Slide 3

Slide 3 text

2 years ago we started to redesign our HTTP API.

Slide 4

Slide 4 text

We decided to develop official clients in several languages.

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

The Go client was leading the development. My approach was to develop a feature in Go, and then in other languages.

Slide 7

Slide 7 text

WriHng Go is certainly a different way of coding.

Slide 8

Slide 8 text

Some design decisions we made in the past also made the API harder to use with certain kinds of languages.

Slide 9

Slide 9 text

Let me show a few examples.

Slide 10

Slide 10 text

Consuming our API with Go allowed us to understand flaws in our response formats and design.

Slide 11

Slide 11 text

// ZoneRecord represents a DNS record in DNSimple.
 type ZoneRecord struct {
 ID int `json:"id,omitempty"`
 Type string `json:"type,omitempty"`
 Name string `json:"name",omitempty`
 Content string `json:"content,omitempty"`
 // ...
 Regions []string `json:"regions,omitempty"`
 } {
 "name": "www",
 "type": "A",
 "content": "127.0.0.1",
 "regions": "global"
 }
 
 {
 "name": "www",
 "type": "A",
 "content": "127.0.0.1",
 "regions": ["TKO", "AMS"]
 }

Slide 12

Slide 12 text

{
 "name": "www",
 "type": "A",
 "content": "127.0.0.1",
 "regions": ["global"]
 }
 
 {
 "name": "www",
 "type": "A",
 "content": "127.0.0.1",
 "regions": ["TKO", "AMS"]
 } // ZoneRecord represents a DNS record in DNSimple.
 type ZoneRecord struct {
 ID int `json:"id,omitempty"`
 Type string `json:"type,omitempty"`
 Name string `json:"name",omitempty`
 Content string `json:"content,omitempty"`
 // ...
 Regions []string `json:"regions,omitempty"`
 }

Slide 13

Slide 13 text

type Domain struct {
 ID int `json:"id,omitempty"`
 Name string `json:"name,omitempty"`
 // ...
 }
 
 // Both accountIdentifier and domainIdentifier
 // may be either an int ID or string Identifier.
 func (s *DomainsService) GetDomain(accountIdentifier, domainIdentifier string) (*DomainResponse, error) {
 // ...
 }


Slide 14

Slide 14 text

type Domain struct {
 ID int `json:"id,omitempty"`
 Name string `json:"name,omitempty"`
 // ...
 }
 
 // Both accountIdentifier and domainIdentifier
 // may be either an int ID or string Identifier.
 func (s *DomainsService) GetDomain(accountIdentifier, domainIdentifier string) (*DomainResponse, error) {
 // ...
 }


Slide 15

Slide 15 text

// ListDomains lists the domains for an account.
 func (s *DomainsService) ListDomains(ID string, o *DomainListOptions) (*DomainsResponse, error) {
 // ...
 }
 
 // DomainListOptions specifies the optional parameters you can provide
 // to customize the DomainsService.ListDomains method.
 type DomainListOptions struct {
 NameLike string `url:"name_like,omitempty"`
 RegistrantID int `url:"registrant_id,omitempty"`
 
 ListOptions
 }
 
 // ListOptions contains the common options you can pass to a List method
 // in order to control parameters such as paginations and page number.
 type ListOptions struct {
 Page int `url:"page,omitempty"`
 PerPage int `url:"per_page,omitempty"`
 Sort string `url:"sort,omitempty"`
 }

Slide 16

Slide 16 text

The simplicity of Go, along with some of its constraints, are features that forced us to rethink the way we designed our API.

Slide 17

Slide 17 text

We used our Go client as the leading implementaHon.

Slide 18

Slide 18 text

// Get the list of domains in Go
 domainsResponse, err := client.Domains.ListDomains(accountID, nil)
 # Get the list of domains in Ruby
 response = client.domains.list_domains(account_id)
 # Get the list of domains in Elixir
 {:ok, response} = Dnsimple.Domains.list_domains(%Dnsimple.Client{}, account_id)
 // Get the list of domains in Node.js
 client.domains.listDomains(accountId).then(function(response) { });
 // Get the list of domains in Java
 ListDomainsResponse response = client.domains.listDomains(accountId);


Slide 19

Slide 19 text

// Get the list of domains in Go
 domainsResponse, err := client.Domains.ListDomains(accountID, nil)
 # Get the list of domains in Ruby
 response = client.domains.list_domains(account_id)
 # Get the list of domains in Elixir
 {:ok, response} = Dnsimple.Domains.list_domains(%Dnsimple.Client{}, account_id)
 // Get the list of domains in Node.js
 client.domains.listDomains(accountId).then(function(response) { });
 // Get the list of domains in Java
 ListDomainsResponse response = client.domains.listDomains(accountId);


Slide 20

Slide 20 text

Thanks! Simone Carle8 @weppos h=ps:/ /dnsimple.com/dotgo