Press ESC to close

Skip to main content
< All Topics
Print

How to Write an API in Golang (REST API Guide)

Overview

If you are looking for how to write API in Golang or how to create REST API in Golang, this knowledge base article provides a structured, production‑ready approach. It covers project setup, routing, request handling, middleware, database integration, testing, and best practices for building reliable services.

This guide explains how to build a basic Golang API and evolve it into a well‑structured RESTful service.

Quick Answer

To build a REST API in Golang, you typically:

  1. Initialize a Go module and project structure
  2. Choose an HTTP router (net/http, chi, gin, echo, etc.)
  3. Define routes and handlers
  4. Parse and validate requests
  5. Return structured JSON responses
  6. Add middleware (logging, recovery, CORS, authentication)
  7. Integrate a database (optional)
  8. Test endpoints and enforce error‑handling standards

Prerequisites

  • Go installed on your system
  • Basic understanding of HTTP methods (GET, POST, PUT, DELETE)
  • A REST client such as Postman, Insomnia, or curl

Recommended Folder Structure

A clean structure helps scalability and maintainability.

my-api/
  cmd/
    server/
      main.go
  internal/
    handler/
    service/
    repository/
  pkg/
  go.mod

Purpose of each layer:

  • cmd/server: Application entry point
  • internal: Private application logic
  • handler: HTTP layer
  • service: Business logic
  • repository: Data access layer

Step 1: Initialize the Project

mkdir my-api && cd my-api
go mod init my-api

Step 2: Build a Basic Golang API Using net/http

This demonstrates how to build a basic Golang API using only the standard library.

package main

import (
    "encoding/json"
    "log"
    "net/http"
)

type HealthResponse struct {
    Status string `json:"status"`
}

func healthHandler(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(HealthResponse{Status: "ok"})
}

func main() {
    http.HandleFunc("/health", healthHandler)

    log.Println("Server running on :8080")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

Run the server:

go run ./cmd/server

Test endpoint:

curl http://localhost:8080/health

Step 3: Understanding REST API Design

REST APIs represent resources and operations using HTTP methods.

Common patterns:

  • GET /users — Retrieve list of users
  • POST /users — Create a new user
  • GET /users/{id} — Retrieve a specific user
  • PUT /users/{id} — Update a user
  • DELETE /users/{id} — Delete a user

This structure is the foundation for how to write REST API in Golang.

Step 4: Use a Router for Production APIs

While net/http works, routers simplify route management and middleware handling.

Example using Chi router:

Install dependency:

go get github.com/go-chi/chi/v5

Sample usage:

r := chi.NewRouter()
r.Get("/health", healthHandler)
r.Get("/users", listUsers)
r.Post("/users", createUser)
http.ListenAndServe(":8080", r)

Step 5: JSON Request and Response Handling

Define request structures (DTOs):

type CreateUserRequest struct {
    Email string `json:"email"`
    Name  string `json:"name"`
}

Typical handler responsibilities:

  • Decode JSON request body
  • Validate required fields
  • Call business logic
  • Return JSON response

Step 6: Standard Response Format (Best Practice)

Consistent response formats improve client integration.

Success Response

{
  "data": { "id": "123", "email": "[email protected]" }
}

Error Response

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "email is required"
  }
}

Step 7: Middleware Integration

Essential middleware for most APIs:

  • Request logging
  • Panic recovery
  • CORS support
  • Authentication (JWT or API keys)

Example with Chi:

r.Use(middleware.Logger)
r.Use(middleware.Recoverer)

Step 8: Database Integration (Optional)

For CRUD operations, connect to a database such as PostgreSQL or MySQL.

Common options:

  • database/sql with drivers
  • pgx (PostgreSQL)
  • gorm (ORM)

Keep database logic inside the repository layer to maintain separation of concerns.

Step 9: Calling External APIs from Golang

If your service needs to consume another REST API:

client := &http.Client{}
req, _ := http.NewRequest("GET", url, nil)
resp, err := client.Do(req)

Parse JSON responses using json.NewDecoder(resp.Body).

Testing Your API

Recommended testing strategies:

  • Unit testing handlers using httptest
  • Integration testing with database
  • Contract testing for external dependencies

Basic test flow:

  1. Create request using httptest.NewRequest
  2. Record response with httptest.NewRecorder
  3. Call handler
  4. Assert status code and response body

Common Mistakes to Avoid

  • Inconsistent error responses
  • Missing input validation
  • Exposing internal errors to clients
  • No request timeouts
  • Mixing database logic inside handlers

Final

You now understand how to create API using Golang, how to build a Golang API, and how to write good API in Golang using REST principles. By following these practices, you can develop scalable, maintainable, and production‑ready backend services.

This approach works for both simple microservices and large distributed systems.

Table of Contents