Building APIs is bread and butter for most programmers. The app platform makes this process even easier by taking care of the infrastructure. Zerops In this article, we will show you how simple it is to build a sample CRUD TODO API written in GO using gin-gonic, one of the most popular web frameworks, which saves your data to the PostgreSQL database. The resulting project is available . here Getting started First and foremost, we need a database system to store and manage our data. In this case, we chose . PostgreSQL Side note: If you prefer a different technology, such as , which Zerops also supports, the process is analogous and the source code can be found . MariaDB here Let's start by running a PostgreSQL server. We can create one very easily in Zerops, either manually or via the Zerops import function. Simply create a new project and add a PostgreSQL service ( ). here’s more about PostgreSQL in Zerops To test the connection or for local development, we can connect to the server with Zerops’ own command line utility called zCLI. After you have the zCLI, follow to log in using a personal access token. The last step is to start a VPN connection by running installed these simple steps $ zcli vpn start [projectName] Now we should be able to test that the server is accessible by running $ ping6 [hostname].zerops # in our case postgresql0.zerops Golang Dependencies We will create the API as a GO module for easier versioning and reproducibility of builds. New GO modules are created with: $ go mod init [api-name] This command creates two files, and , which both contain dependency information. go.mod go.sum The following GO packages are used in this example: github.com/georgysavva/scany (v1.1.0) github.com/gin-contrib/cors (v1.4.0) github.com/gin-gonic/gin (v1.8.1) github.com/jackc/pgx/v4 (v4.17.1) and they can be installed using $ go get [package-url] More information on how to use can be found . go modules here Folder structure This being a sample application, the project structure is very simple. todo-api/ ├── http.go ├── main.go ├── model.go ├── go.mod ├── go.sum ├── schema.sql └── zerops.yml The API source code is contained in the following files: - relating to the HTTP server http.go - for communication with the DB model.go - initialization and wiring of dependencies together main.go This is the bootstrap of the Gin framework which is enough for it to run in Zerops. The following is our implementation of the HTTP server. First of all, we need to initialize the server in by calling main.go r := gin.Default() To run the HTTP server smoothly, and not just in Zerops, we use several middlewares. They include CORS support, better error logging that logs to the Zerops runtime log, and a content-type header addition, which is an example of custom-written middleware. To see the logs in Zerops runtime log, we need to add the following middleware to the gin server. It handles errors and returns 500/4xx error codes depending on the error type. Additionally, it logs failed http requests with 500 to the stdout for Zerops to render on the frontend. r.Use(gin.ErrorLoggerT(gin.ErrorTypePublic | gin.ErrorTypeBind)) Now that we are done with the basic server setup, all that’s left is to register the endpoints. First, we create a router group that will consist of routes with the same path prefix. g := r.Group("todos") This API contains CRUD operations for working with the resource. We register each path to a handler, which processes the corresponding HTTP request. todo url g.GET("", handler.getTodos) g.GET("/:id", handler.getTodo) g.POST("", handler.createTodo) g.PATCH("/:id", handler.editTodo) g.DELETE("/:id", handler.deleteTodo) We have chosen the handler as an example in this blog post. For the full list of handlers, consult the file. getTodos http.go func (t todoHandler) getTodos(c *gin.Context) { todos, err := t.model.FindAll(c.Request.Context()) if err != nil { internalServerError(c, err) return } c.JSON(http.StatusOK, todos) } Finally, we can run this server on port using the following code in the . 3000 main.go log.Fatal(r.Run(":3000")) Running the API locally In the main.go file, there are 3 environment variables used to connect, migrate, and seed the database. We can do this by creating a .env file with the following content: ZEROPS_RECIPE_DATA_SEED=["Buy milk", "Write Zerops article"] ZEROPS_RECIPE_DROP_TABLE=1 DB_URL=postgres://${user}:${password}@${hostname}:5432/${hostname} To get the , and values, see in Zerops GUI. user password hostname environment variables Make sure you have the zCLI VPN up and running to proceed here. Run this command to set the environment variables and run the API: $ source .env && go run main.go http.go model.go Running the API in Zerops After we completed the development of the API, and tested its functionality locally, it's time to deploy it to Zerops. To do that, we need to create a configuration file called , which contains steps to build and deploy our app. For GO, this file is rather simple and looks like this: zerops.yml api: build: base: [ go@1 ] build: - go build -o app main.go model.go http.go deploy: [ app ] run: start: ./app The simplest way to deploy our API to Zerops is to integrate it as an external or repository. We need to create a service in Zerops. The easiest way to configure the API is to paste the environment variables in the file format, defined in . GitHub GitLab Golang .env Running the API locally Once the service is created, we enable a subdomain, which is a domain used for development and testing purposes. When we access it, we will see a response with todo entries from the variable. ZEROPS_RECIPE_DATA_SEED That's it! Conclusion Hopefully, you managed to follow this article and deploy the API to Zerops successfully. If you have any further questions, visit our . Discord channel This story was first published here.