Search
left arrowBack
Pavel Rykov

Pavel Rykov

March 29, 2023 ・ Code

Switching to GoLang from PHP (2 of 3)

In the first part of this tutorial series, we created a simple CRUD API using PHP Laravel. In this second part, we will convert the PHP Laravel application to GoLang while maintaining its functionality.

Getting Started with GoLang

GoLang, or simply Go, is a statically-typed, compiled programming language developed by Google. It is designed to be simple, efficient, and reliable, making it an excellent choice for building web applications and APIs. GoLang has gained popularity due to its performance, concurrency support, and ease of deployment.

Setting up the GoLang Environment

To begin with, we need to set up the GoLang environment. Download and install the latest version of Go from the official website: https://golang.org/dl/

Follow the installation instructions for your operating system. Once installed, verify the installation by running the following command in your terminal:

go version

Screenshot_20230531_143958.jpg

Creating a GoLang Web Server

To create a GoLang web server, we will use the "net/http" package, which is included in the standard library. Create a new directory for your project and a main.go file inside it:

mkdir go-crud-api
cd go-crud-api
touch main.go

Open the main.go file and add the following code to set up a basic web server:

package main

import (
	"fmt"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "Hello, World!")
	})

	http.ListenAndServe(":8080", nil)
}

Run the server using the following command:

go run main.go

You should see the "Hello, World!" message when you visit http://localhost:8080 in your browser.

Designing the GoLang Data Model

In this chapter, we will create a GoLang data model for our users. First, let's create a models directory and a user.go file inside it:

mkdir models
touch models/user.go

Open the user.go file and define the User struct:

package models

import "time"

type User struct {
	ID        int       `json:"id"`
	Name      string    `json:"name"`
	Email     string    `json:"email"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

Here, we use struct tags to define how the struct fields should be serialized to JSON.

Implementing the GoLang API Handlers

In this chapter, we will implement the API handlers for our GoLang application. First, create a new directory named handlers and a file named user_handler.go inside it:

mkdir handlers
touch handlers/user_handler.go

Open the user_handler.go file and add the following code to handle CRUD operations:

package handlers

import (
	"encoding/json"
	"net/http"
	"strconv"

	"github.com/gorilla/mux"
	"go-crud-api/models
)

var users = []models.User{
	{ID: 1, Name: "John Doe", Email: "john@example.com", CreatedAt: time.Now(), UpdatedAt: time.Now()},
	{ID: 2, Name: "Jane Doe", Email: "jane@example.com", CreatedAt: time.Now(), UpdatedAt: time.Now()},
}

func GetUsers(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(users)
}

func GetUser(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	params := mux.Vars(r)
	id, _ := strconv.Atoi(params["id"])

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

	json.NewEncoder(w).Encode(&models.User{})
}

func CreateUser(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	var newUser models.User
	json.NewDecoder(r.Body).Decode(&newUser)
	newUser.ID = len(users) + 1
	newUser.CreatedAt = time.Now()
	newUser.UpdatedAt = time.Now()
	users = append(users, newUser)
	json.NewEncoder(w).Encode(newUser)
}

func UpdateUser(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	params := mux.Vars(r)
	id, _ := strconv.Atoi(params["id"])

	for index, user := range users {
		if user.ID == id {
			users = append(users[:index], users[index+1:]...)
			var updatedUser models.User
			json.NewDecoder(r.Body).Decode(&updatedUser)
			updatedUser.ID = id
			updatedUser.CreatedAt = user.CreatedAt
			updatedUser.UpdatedAt = time.Now()
			users = append(users, updatedUser)
			json.NewEncoder(w).Encode(updatedUser)
			return
		}
	}
}

func DeleteUser(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	params := mux.Vars(r)
	id, _ := strconv.Atoi(params["id"])

	for index, user := range users {
		if user.ID == id {
			users = append(users[:index], users[index+1:]...)
			break
		}
	}

	json.NewEncoder(w).Encode(users)
}

Handling Routing and Middleware in GoLang

For routing and middleware, we will use the popular "gorilla/mux" package. First, install the package by running the following command:

go get -u github.com/gorilla/mux

Next, update the main.go file to include routing and the CRUD API handlers:

package main

import (
	"net/http"

	"github.com/gorilla/mux"
	"go-crud-api/handlers"
)

func main() {
	r := mux.NewRouter()

	r.HandleFunc("/api/users", handlers.GetUsers).Methods("GET")
	r.HandleFunc("/api/users/{id}", handlers.GetUser).Methods("GET")
	r.HandleFunc("/api/users", handlers.CreateUser).Methods("POST")
	r.HandleFunc("/api/users/{id}", handlers.UpdateUser).Methods("PUT")
	r.HandleFunc("/api/users/{id}", handlers.DeleteUser).Methods("DELETE")

	http.ListenAndServe(":8080", r)
}

Testing the GoLang CRUD API

With the GoLang CRUD API complete, you can now test it using tools like Postman or curl. But first, start the server by running the following command:

go run main.go

The server should now be running on http://localhost:8080. Use the following example requests to test the API endpoints:

  • List all users (GET): http://localhost:8080/api/users

  • Get a specific user (GET): http://localhost:8080/api/users/{id}

  • Create a new user (POST): http://localhost:8080/api/users

  • Update a user (PUT): http://localhost:8080/api/users/{id}

  • Delete a user (DELETE): http://localhost:8080/api/users/{id}

Feel free to test the API using the provided examples and any additional scenarios you'd like to explore.

user-crud-api.json

You can import user-crud-api.json configuration into Postman to test the GoLang CRUD API endpoints.

In conclusion, you have now successfully converted a PHP Laravel CRUD API to a GoLang equivalent. You have set up a GoLang environment, created a GoLang web server, designed a data model, implemented handlers, and configured routing and middleware.

In the final part of this tutorial series, we will discuss the benefits of switching from PHP to GoLang and how it can lead to improved performance, concurrency, and ease of deployment in your web applications and APIs.

  • Code