Go back

Golang CRUD API

Here is a full implementation of a basic backend for your contact management application in Golang, structured properly for a CRUD-based API. This example uses Go's gorilla/mux for routing and a simple in-memory list for storing contacts. Later, you can expand it to work with a database.

Folder Structure:

contact-app/
│
├── cmd/
│   └── server/
│       └── main.go
│
├── config/
│
├── controllers/
│   └── contact_controller.go
│
├── models/
│   └── contact.go
│
├── repository/
│
└── routes/
    └── contact_routes.go

1. main.go (Server Entry Point)

This is the entry point for your application, where you initialize the router and start the HTTP server.

package main

import (
    "log"
    "net/http"
    "contact-app/routes"
    "github.com/gorilla/mux"
)

func main() {
    // Initialize the router
    router := mux.NewRouter()

    // Register routes from the routes package
    routes.RegisterRoutes(router)

    // Start the server
    log.Println("Server starting on port 8080...")
    log.Fatal(http.ListenAndServe(":8080", router))
}

2. contact_routes.go (Routing Setup)

In this file, we define all the routes and link them to the respective controller functions.

package routes

import (
    "github.com/gorilla/mux"
    "contact-app/controllers"
)

func RegisterRoutes(router *mux.Router) {
    router.HandleFunc("/contacts", controllers.GetAllContacts).Methods("GET")
    router.HandleFunc("/contacts/{id}", controllers.GetContactByID).Methods("GET")
    router.HandleFunc("/contacts", controllers.CreateContact).Methods("POST")
    router.HandleFunc("/contacts/{id}", controllers.UpdateContact).Methods("PUT")
    router.HandleFunc("/contacts/{id}", controllers.DeleteContact).Methods("DELETE")
}

3. contact_controller.go (Controller Logic)

Here, you handle the logic for each CRUD operation. In this case, we're using an in-memory slice to store contacts.

package controllers

import (
    "encoding/json"
    "net/http"
    "strconv"
    "github.com/gorilla/mux"
    "contact-app/models"
)

var contacts []models.Contact

// GetAllContacts - Fetches all contacts
func GetAllContacts(w http.ResponseWriter, r *http.Request) {
    json.NewEncoder(w).Encode(contacts)
}

// GetContactByID - Fetches a single contact by its ID
func GetContactByID(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    id, _ := strconv.Atoi(params["id"])

    for _, contact := range contacts {
        if contact.ID == id {
            json.NewEncoder(w).Encode(contact)
            return
        }
    }

    http.Error(w, "Contact not found", http.StatusNotFound)
}

// CreateContact - Adds a new contact
func CreateContact(w http.ResponseWriter, r *http.Request) {
    var contact models.Contact
    json.NewDecoder(r.Body).Decode(&contact)

    contact.ID = len(contacts) + 1
    contacts = append(contacts, contact)
    json.NewEncoder(w).Encode(contact)
}

// UpdateContact - Updates an existing contact by ID
func UpdateContact(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    id, _ := strconv.Atoi(params["id"])

    for i, contact := range contacts {
        if contact.ID == id {
            var updatedContact models.Contact
            json.NewDecoder(r.Body).Decode(&updatedContact)
            contacts[i] = updatedContact
            contacts[i].ID = id
            json.NewEncoder(w).Encode(contacts[i])
            return
        }
    }

    http.Error(w, "Contact not found", http.StatusNotFound)
}

// DeleteContact - Deletes a contact by ID
func DeleteContact(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    id, _ := strconv.Atoi(params["id"])

    for i, contact := range contacts {
        if contact.ID == id {
            contacts = append(contacts[:i], contacts[i+1:]...)
            json.NewEncoder(w).Encode(contacts)
            return
        }
    }

    http.Error(w, "Contact not found", http.StatusNotFound)
}

4. contact.go (Contact Model)

This file defines the structure of a contact. Later, you can integrate this model with a database by adding fields such as gorm.Model.

package models

type Contact struct {
    ID    int    `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
    Phone string `json:"phone"`
}

5. Test Your Application

Once the code is ready, you can start the server:

cd cmd/server
go run main.go

The server will start on port 8080. You can test the routes using tools like Postman or curl.

Sample curl commands:

  • Create a Contact:
    curl -X POST -H "Content-Type: application/json" \
    -d '{"name": "John Doe", "email": "john@example.com", "phone": "1234567890"}' \
    http://localhost:8080/contacts
    
  • Get All Contacts:
    curl http://localhost:8080/contacts
    
  • Update a Contact:
    curl -X PUT -H "Content-Type: application/json" \
    -d '{"name": "John Smith", "email": "johnsmith@example.com", "phone": "0987654321"}' \
    http://localhost:8080/contacts/1
    
  • Delete a Contact:
    curl -X DELETE http://localhost:8080/contacts/1
    

Summary:

  • The above code demonstrates a basic CRUD backend built with Go.
  • You can expand this structure by adding more sophisticated features such as database connectivity (e.g., GORM), user authentication, and middleware for logging or error handling.

Share this post on: