api |go

Build REST API with Go Fiber and PlanetScale - Part 3

maful

Maful

Posted on October 19, 2022

Build REST API with Go Fiber and PlanetScale - Part 3

Deploy the schema

Now, it is time to deploy the add-users-table branch into the main branch

$ pscale deploy-request create fiber-pscale add-users-table
Deploy request #1 successfully created.
Enter fullscreen mode Exit fullscreen mode

Now check your dashboard, you'll see here that you requested schema changes from the development branch to the main branch. If you are familiar with Git, it is similar to Pull Request.

Deploy Request In Review

Now, approve the request and PlanetScale automatically apply the new schema into the main branch without downtime.

$ pscale deploy-request deploy fiber-pscale 1
Successfully deployed dhacze78ukhv from add-users-table to main.
Enter fullscreen mode Exit fullscreen mode

Now, back and check the dashboard, it's deployed!🎊

Deploy Request Deployed

if you no longer need to make schema changes from the branch, now you can safely delete it.

$ pscale branch delete fiber-pscale add-users-table
Enter fullscreen mode Exit fullscreen mode

Handlers

Create a file called users.go inside the handlers directory. And now, create a connection to the main branch so the application can communicate with the database.

$ pscale connect fiber-pscale main --port 3309
Enter fullscreen mode Exit fullscreen mode

Note: It's recommended to use a secure connection while connecting to the main branch once you deployed your application. More https://docs.planetscale.com/reference/secure-connections

Create a user

Create a function CreateUser and initialize createUserRequest struct in users.go.

package handlers

import (
    "net/http"

    "github.com/gofiber/fiber/v2"
    "github.com/maful/fiber-pscale/models"
)

type createUserRequest struct {
    Name    string `json:"name" binding:"required"`
    Email   string `json:"email" binding:"required"`
    Website string `json:"website" binding:"required"`
}

func CreateUser(c *fiber.Ctx) error {
    req := &createUserRequest{}
    if err := c.BodyParser(req); err != nil {
        return c.Status(http.StatusBadRequest).JSON(&fiber.Map{
            "message": err.Error(),
        })
    }
    user := models.User{
        Name:    req.Name,
        Email:   req.Email,
        Website: req.Website,
    }
    models.DB.Create(&user)
    return c.Status(fiber.StatusCreated).JSON(&fiber.Map{
        "user": user,
    })
}
Enter fullscreen mode Exit fullscreen mode

open main.go, add a new handler to call that function

import (
    // ...
    "github.com/maful/fiber-pscale/handlers"
)

// app.Get("/" ...
app.Post("/users", handlers.CreateUser)
Enter fullscreen mode Exit fullscreen mode

run the app, and try to create the user

$ curl --location --request POST 'http://localhost:3000/users' \
--header 'Content-Type: application/json' \
--data-raw '{
    "name": "John",
    "email": "john@example.com",
    "website": "https://example.com"
}'
Enter fullscreen mode Exit fullscreen mode

response

{
  "user": {
    "ID": 1,
    "CreatedAt": "2021-09-06T20:04:31.022+07:00",
    "UpdatedAt": "2021-09-06T20:04:31.022+07:00",
    "DeletedAt": null,
    "name": "John",
    "email": "john@example.com",
    "website": "https://example.com"
  }
}
Enter fullscreen mode Exit fullscreen mode

List all users

Create a new function called GetUsers below the create function.

func GetUsers(c *fiber.Ctx) error {
    var users []models.User
    models.DB.Find(&users)

    return c.Status(http.StatusOK).JSON(&fiber.Map{
        "users": users,
    })
}
Enter fullscreen mode Exit fullscreen mode

Register the function to the app, place it above the create user handler.

app.Get("/users", handlers.GetUsers)
// app.Post("/users...
Enter fullscreen mode Exit fullscreen mode

stop the existing app, and run again. You should always do this because the app doesn't refresh automatically when we made changes.

curl --location --request GET 'http://localhost:3000/users'
Enter fullscreen mode Exit fullscreen mode

response

{
  "users": [
    {
      "ID": 1,
      "CreatedAt": "2021-09-06T20:04:31.022+07:00",
      "UpdatedAt": "2021-09-06T20:04:31.022+07:00",
      "DeletedAt": null,
      "name": "John",
      "email": "john@example.com",
      "website": "https://example.com"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

View user

Add a new function called GetUser in the bottom.

func GetUser(c *fiber.Ctx) error {
    var user models.User
    if err := models.DB.First(&user, "id = ?", c.Params("id")).Error; err != nil {
        return c.Status(http.StatusNotFound).JSON(&fiber.Map{
            "message": "Record not found!",
        })
    }

    return c.Status(http.StatusOK).JSON(&fiber.Map{
        "user": user,
    })
}
Enter fullscreen mode Exit fullscreen mode

and add a new handler in main.go

// ...
app.Get("/users", handlers.GetUsers)
app.Get("/users/:id", handlers.GetUser) // new
Enter fullscreen mode Exit fullscreen mode

now, we try to get the user details with id 1

curl --location --request GET 'http://localhost:3000/users/1'
Enter fullscreen mode Exit fullscreen mode

response

{
  "user": {
    "ID": 1,
    "CreatedAt": "2021-09-06T20:04:31.022+07:00",
    "UpdatedAt": "2021-09-06T20:04:31.022+07:00",
    "DeletedAt": null,
    "name": "John",
    "email": "john@example.com",
    "website": "https://example.com"
  }
}
Enter fullscreen mode Exit fullscreen mode

if try to get the id that doesn't exist

curl --location --request GET 'http://localhost:3000/users/100'
Enter fullscreen mode Exit fullscreen mode
{
  "message": "Record not found!"
}
Enter fullscreen mode Exit fullscreen mode
💖 💪 🙅 🚩
maful
Maful

Posted on October 19, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related