How To Build And Deploy A CRUD API Using Go And PipeOps.

How To Build And Deploy A CRUD API Using Go And PipeOps.

APIs have become an integral part of modern software development, enabling different systems to communicate with each other seamlessly. However, building and deploying an API can be a daunting task, especially for developers new to the process. In this article, we will explore how to build and deploy a simple CRUD(Create, Read, Update, and Delete) API with Go and PipeOps. We will walk you through the steps required to create a simple API, including setting up a development environment, defining endpoints, and deploying your API on PipeOps. By the end of this article, you will have a solid understanding of how to create and deploy a robust API using these powerful tools.

What do you need to get started?

Before we get started, here's what you'll need:

  • Basic knowledge of Go programming language

  • Basic understanding of REST APIs

  • A PipeOps account

Setting up the environment

First, create a new directory for your project and initialize a new Go module inside it. Open your terminal and run the following commands:

// Create a new project folder named 'crudapi'
$ mkdir crudapi

// Move into the 'crudapi' directory to begin working on our project
$ cd crudapi

// Initialize a new Go module
$ go mod init crudapi

Building the CRUD API

Now that our development environment is set up, we can start building our simple CRUD API using Go and Gin without a database. Here's how to do it:

  1. Firstly we need to install the Gin web framework using the following command
$ go get -u github.com/gin-gonic/gin
  1. Create two Go files in your project directory called main.go and model.go

  2. In your model.go file add the code below:

package main

type Task struct {
    ID          string `json:"id"`
    Title       string `json:"title"`
    Description string `json:"description"`
    Completed   bool   `json:"completed"`
}

type Tasks []Task

In this model, we define a Task struct with four fields: ID, Title, Description, and Completed. We also define a Tasks type, which is just a slice of Task objects.

4: Define the API Routes in your main.go file

package main

import (
    "net/http"
    "log"
    "os"

    "github.com/gin-gonic/gin"
)

// Create a slice to store the tasks
var tasks Tasks

func main() {
    // Create a new router with default middleware
    router := gin.Default()

    // Set up routes
    router.GET("/tasks", getTasks)           // Get all tasks
    router.GET("/tasks/:id", getTask)        // Get a specific task by ID
    router.POST("/tasks", createTask)        // Create a new task
    router.PUT("/tasks/:id", updateTask)     // Update a task by ID
    router.DELETE("/tasks/:id", deleteTask)  // Delete a task by ID

    // Start the server on port 8080 or production port
    port := os.Getenv("PORT")
    if port == "" {
        port = "8080"
    }
    if err := router.Run(":" + port); err != nil {
        log.Panicf("error: %s", err)
    }
}

// Get all tasks
func getTasks(c *gin.Context) {
    c.JSON(http.StatusOK, tasks)
}

// Get a specific task by ID
func getTask(c *gin.Context) {
    id := c.Param("id")
    for _, task := range tasks {
        if task.ID == id {
            c.JSON(http.StatusOK, task)
            return
        }
    }
    c.JSON(http.StatusNotFound, gin.H{"error": "Task not found"})
}

// Create a new task
func createTask(c *gin.Context) {
    var task Task
    if err := c.BindJSON(&task); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }

    tasks = append(tasks, task)
    c.JSON(http.StatusCreated, task)
}

// Update a task by ID
func updateTask(c *gin.Context) {
    id := c.Param("id")
    var updatedTask Task
    if err := c.BindJSON(&updatedTask); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }

    for i, task := range tasks {
        if task.ID == id {
            updatedTask.ID = task.ID
            tasks[i] = updatedTask
            c.JSON(http.StatusOK, updatedTask)
            return
        }
    }
    c.JSON(http.StatusNotFound, gin.H{"error": "Task not found"})
}

// Delete a task by ID
func deleteTask(c *gin.Context) {
    id := c.Param("id")
    for i, task := range tasks {
        if task.ID == id {
            tasks = append(tasks[:i], tasks[i+1:]...)
            c.JSON(http.StatusNoContent, nil)
            return
        }
    }
    c.JSON(http.StatusNotFound, gin.H{"error": "Task not found"})
}

In the above code, we define five API routes:

  • GET /tasks: Returns a list of all tasks.

  • GET /tasks/:id: Returns a specific task by ID.

  • POST /tasks: Creates a new task.

  • PUT /tasks/:id: Updates an existing task by ID.

  • DELETE /tasks/:id: Deletes a task by ID.

For each route, we define a handler function that processes the incoming request and returns a response.

  1. Test the API: To test the API, run the following command in your terminal:
$ go run main.go

This will start the API server on http://localhost:8080. You can use tools like Curl, Postman, and Thunder Client to test the API.

Here are some example requests using Thunder Client:

Deploying the API with PipeOps

Now that we've built our API, it's time to deploy it to the cloud so that it can run 24/7. This is where PipeOps comes in.

First, we need to create a new web project on Pipeops:

you need to select Github as your repository source. After that, you can select your account name to access the list of repositories that you own. From there, select the crudapi repository to work with after that click on proceed.

You will see the image below. You can also update your environment from beta to production, but for this case, we will use Beta.

After clicking the "Proceed" button, you will be redirected to the project build settings page. Here, you can select the framework and the build method that you prefer. Pipeops also offers a feature where you can add your project environment variables to customize your deployment.

💡 To use the Heroku Buildpack as your build method, you'll need to create a Procfile inside your crudapi project.

Click on the "Deploy Project" button to deploy your crudapi project. Once the deployment is complete, you will see a success message as shown in the image below.

Test the API using Thunder Client:

Conclusion

In conclusion, building and deploying a CRUD API with Go and PipeOps is a relatively straightforward process that even new developers can learn. We have learned the basics of setting up our development environment, defining endpoints, and deploying the API on PipeOps. Using the Gin web framework, we have created an API with five endpoints, including GET, POST, PUT, and DELETE methods. Go provides us with a robust and fast language, and PipeOps simplifies deployment by automating the pipeline process. This article has provided you with the foundational knowledge you need to create and deploy robust APIs with Go and PipeOps, and with continued practice and exploration, you can take your API development to the next level.