There are many ways to build an API server but I will start with REST this time. To build the server faster, I will use Gin to implement the REST API.
First, create a Go module
mkdir rest-api
cd rest-api
go mod init gorest
touch main.go
I'm going to create the server for making a TODO program
type TODO struct {
Title string
Done bool
}
type TODOS []*TODO
func (todos *TODOS) AddItem(title string) {
for _, todo := range *todos {
if todo.Title == title {
return
}
}
*todos = append(*todos, &TODO{Title: title})
}
func (todos TODOS) MarkDone(title string) {
for _, todo := range todos {
if todo.Title == title {
todo.Done = true
return
}
}
}
func (todos *TODOS) RemoveItem(title string) {
pos := -1
for i, todo := range *todos {
if todo.Title == title {
pos = i
break
}
}
if pos == -1 {
return
}
*todos = append((*todos)[:pos], (*todos)[pos+1:]...)
}
Next, create endpoints for the server
func main() {
r := gin.Default()
r.GET("todos", func(ctx *gin.Context) {})
r.POST("todo", func(ctx *gin.Context) {})
r.PATCH("todo", func(ctx *gin.Context) {})
r.DELETE("todo", func(ctx *gin.Context) {})
}
Then implement each endpoint.
Get all TODOs
r.GET("todos", func(ctx *gin.Context) {
ctx.JSON(http.StatusOK, todos.GetTODOList())
})
Add a new TODO
r.POST("todo", func(ctx *gin.Context) {
var todo TODO
if err := ctx.ShouldBindJSON(&todo); err != nil {
log.Println(err)
ctx.String(http.StatusUnprocessableEntity, "Wrong format")
return
}
todos.AddItem(todo.Title)
ctx.String(http.StatusCreated, "The new TODO has been added")
})
Mark a TODO as done
r.PATCH("todo", func(ctx *gin.Context) {
var todo TODO
if err := ctx.ShouldBindJSON(&todo); err != nil {
ctx.String(http.StatusUnprocessableEntity, "Wrong format")
return
}
todos.MarkDone(todo.Title)
ctx.String(http.StatusOK, "Your TODO has been marked as done")
})
Delete a TODO
r.DELETE("todo", func(ctx *gin.Context) {
var todo TODO
if err := ctx.ShouldBindJSON(&todo); err != nil {
ctx.String(http.StatusUnprocessableEntity, "Wrong format")
return
}
todos.RemoveItem(todo.Title)
ctx.String(http.StatusOK, "Your TODO is deleted successfully")
})
Now run the server by this (the default port is 8080)
func main() {
r := gin.Default()
.
.
.
r.Run()
}
Test the server with REST Client
@API = http://localhost:8080
###
POST {{API}}/todo
Content-Type: application/json
{
"Title": "Wake up at 6 a.m."
}
###
POST {{API}}/todo
Content-Type: application/json
{
"Title": "Eat breakfast"
}
###
PATCH {{API}}/todo
Content-Type: application/json
{
"Title": "Wake up at 6 a.m."
}
###
GET {{API}}/todos
###
DELETE {{API}}/todo
Content-Type: application/json
{
"Title": "Eat breakfast"
}
There is more to do about the server like CORS to make it usable with other applications. Please follow this link. Thank you for reading!
sources