Mapbox API API in Go
Mapbox API API in Go
This guide shows you how to integrate the Mapbox API into your Go application. Custom maps, geocoding, directions, and satellite imagery with GL JS and mobile SDKs.
Prerequisites
- Go installed on your system
- An Mapbox API API key (sign up at https://mapbox.com)
- Basic familiarity with HTTP APIs
Installation
go mod init myapp
go get github.com/go-resty/resty/v2
Basic Usage
package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
apiKey := os.Getenv("API_KEY")
if apiKey == "" {
apiKey = "YOUR_API_KEY"
}
baseURL := "https://api.mapbox.com"
req, _ := http.NewRequest("GET", baseURL+"/v1/resources", nil)
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
fmt.Println("Error:", err)
return
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println("Status:", resp.Status)
fmt.Println(string(body))
}
Error Handling
package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func callAPIWithRetry(url, apiKey string, maxRetries int) ([]byte, error) {
var lastErr error
for attempt := 0; attempt < maxRetries; attempt++ {
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Authorization", "Bearer "+apiKey)
resp, err := http.DefaultClient.Do(req)
if err != nil {
lastErr = err
time.Sleep(time.Duration(1<<attempt) * time.Second)
continue
}
if resp.StatusCode == 429 {
retryAfter := resp.Header.Get("Retry-After")
fmt.Println("Rate limited. Retry-After:", retryAfter)
resp.Body.Close()
time.Sleep(60 * time.Second)
continue
}
if resp.StatusCode >= 400 {
body, _ := io.ReadAll(resp.Body)
resp.Body.Close()
lastErr = fmt.Errorf("HTTP %d: %s", resp.StatusCode, string(body))
time.Sleep(time.Duration(1<<attempt) * time.Second)
continue
}
body, err := io.ReadAll(resp.Body)
resp.Body.Close()
return body, err
}
return nil, lastErr
}
func main() {
apiKey := os.Getenv("API_KEY")
body, err := callAPIWithRetry("https://api.mapbox.com/v1/resources", apiKey, 3)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(string(body))
}
Advanced Usage
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
type MapboxClient struct {
APIKey string
BaseURL string
HTTP *http.Client
}
func NewClient(apiKey, baseURL string) *MapboxClient {
return &MapboxClient{
APIKey: apiKey,
BaseURL: baseURL,
HTTP: &http.Client{Timeout: 30 * time.Second},
}
}
func (c *MapboxClient) do(method, path string, body interface{}) ([]byte, error) {
var reqBody io.Reader
if body != nil {
jsonData, _ := json.Marshal(body)
reqBody = bytes.NewBuffer(jsonData)
}
req, _ := http.NewRequest(method, c.BaseURL+path, reqBody)
req.Header.Set("Authorization", "Bearer "+c.APIKey)
req.Header.Set("Content-Type", "application/json")
resp, err := c.HTTP.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
return io.ReadAll(resp.Body)
}
func (c *MapboxClient) ListResources() ([]byte, error) {
return c.do("GET", "/v1/resources", nil)
}
func (c *MapboxClient) CreateResource(data map[string]interface{}) ([]byte, error) {
return c.do("POST", "/v1/resources", data)
}
func main() {
client := NewClient(os.Getenv("API_KEY"), "https://api.mapbox.com")
resources, err := client.ListResources()
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(string(resources))
}
Best Practices
- Store your API key in an environment variable, never in source code
- Implement retry logic with exponential backoff for 429 and 5xx errors
- Set reasonable timeouts (10-30 seconds) for all API calls
- Log request IDs from response headers for debugging
- Cache responses where appropriate to reduce API calls