Back

Step by Step Guide to Building a Fathom API Integration in Go

Aug 15, 2024 • 6 minute read

Introduction

Hey there, fellow Go enthusiast! Ready to dive into the world of Fathom analytics? In this guide, we'll walk through building a slick Fathom API integration using Go. Fathom's API is a powerhouse for fetching site stats, and we're going to harness that power with some clean, efficient Go code. Let's get cracking!

Prerequisites

Before we jump in, make sure you've got:

  • Go installed (I know you probably do, but just checking!)
  • A Fathom API key (grab one from your Fathom dashboard)
  • Your favorite code editor at the ready

Setting up the project

Let's kick things off by setting up our project:

mkdir fathom-go-integration cd fathom-go-integration go mod init github.com/yourusername/fathom-go-integration

Authentication

Fathom uses API keys for authentication. Let's set that up:

const apiKey = "your-api-key-here" client := &http.Client{} req, _ := http.NewRequest("GET", "https://api.usefathom.com/v1/account", nil) req.Header.Add("Authorization", "Bearer "+apiKey)

Making API requests

Time to create our HTTP client and handle those pesky rate limits:

func createClient() *http.Client { return &http.Client{ Timeout: time.Second * 10, Transport: &http.Transport{ MaxIdleConns: 10, IdleConnTimeout: 30 * time.Second, }, } } func makeRequest(client *http.Client, req *http.Request) (*http.Response, error) { resp, err := client.Do(req) if err != nil { return nil, err } if resp.StatusCode == http.StatusTooManyRequests { time.Sleep(time.Second * 5) return makeRequest(client, req) } return resp, nil }

Implementing core Fathom API endpoints

Let's tackle some key endpoints:

func getSiteStats(client *http.Client, siteID string) ([]byte, error) { req, _ := http.NewRequest("GET", fmt.Sprintf("https://api.usefathom.com/v1/sites/%s/aggregations", siteID), nil) req.Header.Add("Authorization", "Bearer "+apiKey) resp, err := makeRequest(client, req) if err != nil { return nil, err } defer resp.Body.Close() return ioutil.ReadAll(resp.Body) } // Implement similar functions for current visitors and top pages

Error handling and logging

Don't forget to handle those errors gracefully:

import "log" // In your functions if err != nil { log.Printf("Error fetching site stats: %v", err) return nil, err }

Creating a reusable Fathom client

Let's wrap this all up in a neat package:

type FathomClient struct { client *http.Client apiKey string } func NewFathomClient(apiKey string) *FathomClient { return &FathomClient{ client: createClient(), apiKey: apiKey, } } func (fc *FathomClient) GetSiteStats(siteID string) ([]byte, error) { // Implement using the methods we created earlier } // Add more methods as needed

Example usage

Here's how you might use our shiny new client:

func main() { client := NewFathomClient("your-api-key") stats, err := client.GetSiteStats("your-site-id") if err != nil { log.Fatalf("Error: %v", err) } fmt.Println(string(stats)) }

Testing

Don't forget to test! Here's a quick example:

func TestGetSiteStats(t *testing.T) { // Set up test server to mock Fathom API // Test your GetSiteStats function // Assert expected results }

Performance optimization

Want to speed things up? Consider implementing caching:

var ( cache = make(map[string][]byte) cacheMutex sync.RWMutex ) func (fc *FathomClient) GetSiteStatsWithCache(siteID string) ([]byte, error) { cacheMutex.RLock() if data, ok := cache[siteID]; ok { cacheMutex.RUnlock() return data, nil } cacheMutex.RUnlock() data, err := fc.GetSiteStats(siteID) if err != nil { return nil, err } cacheMutex.Lock() cache[siteID] = data cacheMutex.Unlock() return data, nil }

Conclusion

And there you have it! You've just built a robust Fathom API integration in Go. From authentication to error handling, we've covered the essentials. Remember, this is just the beginning – feel free to expand on this foundation and add more features as you need them.

Resources

Happy coding, and may your analytics be ever insightful!