Taskilfy with Go ( API )
Let's play again with Go ?? .
In this article , We'll be building API for managing Task with pure Go .
Let's dive into .
First we need to know what will have to build .
I didn't want to use any DB for this therefore we need to defile our task as struct
// Task entity
type Task struct {
Id int `json:"Id"`
Title string `json:"Title"`
Status string `json:"Status"`
}
Then Routes
// Get all tasks
{{url}}/all
// Add new task
{{url}}/add
// Get a task by id
{{url}}?id = number
// Update task
{{url}}/edit?id=number
// Delete task by id
{{url}}/delete?id=number
Init go mod
go mod init example.com/greetings
Every go project , There should be main file
// main.go
package main
import (
"net/http"
"fmt"
)
func main(){
http.HandleFunc("/",func(w http.ResponseWriter, r *http.Request){
fmt.Fprint(w,"Hello World")
})
http.ListenAndServe(":3000")
}
go run main.go
result should be "Hello World"
Time to build folders structure
We will start with defining our routes . we can use mux package to navigate them.
package Routes
import (
controller "Tasklify/Controllers"
util "Tasklify/Utils"
"github.com/gorilla/mux"
"log"
"net/http"
)
func Router() {
myRouter := mux.NewRouter().StrictSlash(true)
myRouter.HandleFunc("/all", controller.GetAll)
myRouter.HandleFunc("/", controller.GetOneById)
myRouter.HandleFunc("/add", controller.AddTask)
myRouter.HandleFunc("/edit", controller.EditTask)
myRouter.HandleFunc("/delete", controller.DeleteTaskById)
port := util.GetEnv("PORT")
log.Fatal(http.ListenAndServe(port, myRouter))
}
领英推荐
Time to Define our controllers
First Users can get all tasks
// Tasklify/Controllers/GetAll.go
package controller
import (
"fmt"
"net/http"
"os"
)
func GetAll(w http.ResponseWriter, r *http.Request) {
_, err := fmt.Fprint(w, Tasks)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}
Can add new task
// Tasklify/Controllers/AddTask.go
package controller
import (
"Tasklify/Types"
"encoding/json"
"fmt"
"math/rand"
"net/http"
)
func AddTask(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
fmt.Fprint(w, http.StatusBadRequest)
}
var reqBody Types.Task
err := json.NewDecoder(r.Body).Decode(&reqBody)
if err != nil {
fmt.Printf("server: could not read request body: %s\n", err)
return
}
if reqBody.Status == "" || reqBody.Title == "" {
fmt.Fprint(w, http.StatusBadRequest)
return
}
Tasks = append(Tasks, Types.Task{Id: rand.Intn(100), Title: reqBody.Title, Status: reqBody.Status})
fmt.Fprint(w, Tasks)
return
}
Get a task by its id
// Tasklify/Controllers/GetOneById.go
package controller
import (
util "Tasklify/Utils"
"fmt"
"net/http"
)
func GetOneById(w http.ResponseWriter, r *http.Request) {
validId, err := util.GetAndParseIdFromQueryParam(w, r)
if err != nil {
fmt.Fprint(w, http.StatusBadRequest)
return
}
for i := range Tasks {
if Tasks[i].Id == validId {
fmt.Fprint(w, Tasks[i])
return
}
}
fmt.Fprint(w, "Task not found")
return
}
We can change task's title and status by its id
// Tasklify/Controllers/EditTaskById.go
// ! You can see another funcs (GetAndParseIdFromQueryParam,etc) in Utils
package controller
import (
util "Tasklify/Utils"
"fmt"
"net/http"
)
func EditTask(w http.ResponseWriter, r *http.Request) {
if r.Method != "PUT" {
fmt.Fprint(w, http.StatusBadRequest)
return
}
taskId, err := util.GetAndParseIdFromQueryParam(w, r)
if err != nil {
fmt.Fprint(w, http.StatusBadRequest)
return
}
reqBody := util.GetAndParseReqBody(w, r)
tasks, success := util.DeleteOldAndAddNew(Tasks, reqBody, taskId)
if success {
Tasks = tasks
fmt.Fprint(w, Tasks)
return
} else {
fmt.Fprint(w, "Invalid Id or request")
return
}
}
Time to delete from Tasks by id
// Tasklify/Controllers/DeleteTaskById.go
package controller
import (
"Tasklify/Types"
util "Tasklify/Utils"
"fmt"
"net/http"
)
var Tasks = []Types.Task{
{1, "Homework", "wait"},
{2, "reading", "done"},
}
func DeleteTaskById(w http.ResponseWriter, r *http.Request) {
if r.Method != "DELETE" {
fmt.Fprint(w, http.StatusBadRequest)
return
}
taskId, err := util.GetAndParseIdFromQueryParam(w, r)
if err != nil {
fmt.Fprint(w, "Id is invalid")
return
}
Tasks = util.DeleteElementByIdFromSlice(Tasks, taskId)
fmt.Fprint(w, Tasks)
return
}
Result
Whole code
Thanks.