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.
-
Converting an application from PHP to GoLang
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
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.
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