Working with JSON and APIs

The API Integration That Took 3 Days in Python, 4 Hours in Go

It was sprint planning when my manager assigned me: "Integrate with the payment provider's API. Should take a week."

In Python, I'd done this before. The pattern was familiar:

import requests
import json

def create_payment(amount, customer_id):
    response = requests.post(
        "https://api.payment.com/charges",
        headers={"Authorization": f"Bearer {API_KEY}"},
        json={
            "amount": amount,
            "customer_id": customer_id,
            "currency": "USD"
        }
    )
    
    if response.status_code == 200:
        return response.json()
    else:
        raise Exception(f"API error: {response.text}")

But Python's dynamic typing meant runtime surprises. A missing field? Runtime error. Wrong type? Runtime error. API schema change? Production error.

In Go, I rewrote it:

The difference?

  • Compile-time safety: Wrong types = won't compile

  • Self-documenting: Structs show exactly what API expects

  • IDE support: Autocomplete for all fields

  • Zero runtime surprises: Missing fields caught before deploy

I finished the integration in 4 hours. It's been running for 2 years with zero API-related bugs.

This article covers everything I learned about JSON and APIs in Go.


JSON Basics

Marshaling (Go → JSON)

Pretty Printing

Unmarshaling (JSON → Go)


Struct Tags in Detail

Struct tags control JSON encoding/decoding.

Basic Tags

Omit Empty Fields

Ignore Fields

String Tags

Custom Field Names


Handling Nested JSON

Nested Structs

Embedded Structs

Arrays and Slices

Maps


Working with http.Client

Basic GET Request

POST Request

Custom Headers


Building a Reusable API Client

Client Structure

Using the Client


Building REST APIs with net/http

Basic HTTP Server

CRUD API Example


Middleware Pattern


Error Handling in HTTP


Real Example: GitHub API Client

Complete GitHub API client I built for a project:


Your Challenge

Build a weather API client:


Key Takeaways

  1. json.Marshal/Unmarshal: Convert between Go and JSON

  2. Struct tags: Control JSON field names and behavior

  3. http.Client: Make HTTP requests with proper configuration

  4. Reusable clients: Build generic API client structure

  5. net/http: Build REST APIs with standard library

  6. Middleware: Chain handlers for cross-cutting concerns

  7. Error handling: Return structured errors in JSON

  8. Type safety: Compile-time checking prevents runtime errors


What I Learned

That payment API integration taught me that Go's approach to APIs is superior:

  • Type safety caught bugs at compile time, not in production

  • Struct tags made JSON mapping explicit and clear

  • 4-hour integration vs. 3-day Python integration

  • Zero API bugs in 2 years of production use

Coming from Python's dynamic typing and runtime surprises, Go's compile-time safety was revelatory. The payment integration has processed $12M in transactions without a single JSON-related bug.

The time saved debugging API issues? Weeks.


Next: Database Operations

In the next article, we'll dive into database operations. You'll learn connection pooling, prepared statements, transactions, and the PostgreSQL integration that handles 50,000 queries per second.

Last updated