[Go] Lambda CRUD với Postgres

Prepare create simple lambda function, read blog: https://viblo.asia/p/golang-aws-lambda-thong-qua-serverless-framework-phan-1-EoW4ob9xVml handle request and response in api: https://viblo.asia/p/golang-aws-lambda-thong-qua-serverless-framework-phan-2-5pPLkPY8VRZ Mục tiêu add new user get user by id update user delete user Khởi tạo project Ở series này mình dùng serverless để làm việc với lambda(env, create, deploy,..) Để biết chi tiết hơn, checkout link đọc thêm. Script create

Prepare

Mục tiêu

  • add new user
  • get user by id
  • update user
  • delete user

Khởi tạo project

  • Ở series này mình dùng serverless để làm việc với lambda(env, create, deploy,..)
  • Để biết chi tiết hơn, checkout link đọc thêm.

Script create table:

  • sql create table user
    CREATETABLE"users"("id" bigserial,
      username charactervarying(50)COLLATE pg_catalog."default",
      name charactervarying(50)COLLATE pg_catalog."default"NOTNULL,
      phone charactervarying(50)COLLATE pg_catalog."default",PRIMARYKEY("id"));
  • model database
    type UserModel struct{
      ID       uint`gorm:"primarykey"`
      UserName string`gorm:"column:username" bson:"username"`
      Email    string`gorm:"column:email" bson:"email"`
      Phone    string`gorm:"column:phone" bson:"phone"`}

List function

Thêm 1 user

  • tạo endpoint trong file serverless:
functions:create:handler: bin/create # file binary sau khi buildtimeout:3# thời gian tối đa của functoin có thể xử lý memorySize:512# resource memory được cấp phát cho function,description: create new user
    events:-http:path: /create # context-pathmethod: post # method
  • Code implement:
    • function connection đến postgres database:
      // load env from os, cast to structfuncloadConfig() Postgres {// những value khi get từ os lên thì đã được define trong file serverless.yaml
          user := os.Getenv("DB_USER")
          dbpass := os.Getenv("DB_PASS")
          dbhost := os.Getenv("DB_HOST")
          dbservice := os.Getenv("DB_SERVICE")return Postgres{
            Username: user,
            Password: dbpass,
            Database: dbservice,
            Host:     dbhost,
            Port:5432,}}// create database postgres instancefuncInitPostgres()(*gorm.DB,error){
          log.Default().Println("connecting postgres database")
          config :=loadConfig()
          dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%d ", config.Host, config.Username, config.Password, config.Database, config.Port)
          db, err := gorm.Open(postgres.Open(dsn),&gorm.Config{})if err !=nil{
              log.Default().Println("connect postgres err:", err)return db, err
          }
          log.Default().Println("connect postgres successfully")return db, err
      }
    • struct nhận request client:
      type UserDTO struct{
        Email string`json:"email"`
        User  string`json:"userName"`
        Phone string`json:"phone"`}
    • main function của lambda
      funcmain(){
          lambda.Start(CreateUser)}
    • function response data
      funcParseResponse(respBody HttpResponse)string{
        respBody.Time = time.Now().Format("2006-01-02T15:04:05.000-07:00")if respBody.Err !=nil{returnresponseErr(respBody)}returnresponseOk(respBody)}funcresponseOk(respBody HttpResponse)string{var buf bytes.Buffer
        mapRes :=map[string]interface{}{"responseId":      respBody.Uuid,"responseMessage":"successfully","responseTime":    respBody.Time,}if respBody.Data !=nil{
          mapRes["data"]= respBody.Data
        }
        body, errMarshal := json.Marshal(mapRes)if errMarshal !=nil{
          log.Default().Println("marshal response err", errMarshal)}
        json.HTMLEscape(&buf, body)return buf.String()}funcresponseErr(respBody HttpResponse)string{var buf bytes.Buffer
        mapRes :=map[string]interface{}{"responseId":      respBody.Uuid,"responseMessage": respBody.Err.Error(),"responseTime":    respBody.Time,}
      
        body, errMarshal := json.Marshal(mapRes)if errMarshal !=nil{
          log.Default().Println("marshal response err", errMarshal)}
        json.HTMLEscape(&buf, body)return buf.String()}
    • function createUser
      funcCreateUser(ctx context.Context,
        eventReq events.APIGatewayProxyRequest)(Response,error){var(
          req  = RequestBodyAPIGW{}
          resp = Response{
            StatusCode:400,
            IsBase64Encoded:false,
            Headers:map[string]string{"Content-Type":"application/json",},})
        err := json.Unmarshal([]byte(eventReq.Body),&req)if err !=nil{
          resp.Body =ParseResponse(HttpResponse{
            Uuid: req.RequestID,
            Err:  err,})return resp,nil}
        db, err := pkg.InitPostgres()if err !=nil{
          resp.Body =ParseResponse(HttpResponse{
            Uuid: req.RequestID,
            Err:  err,})
          resp.StatusCode =500return resp,nil}// set http-code 200
        resp.StatusCode =200// save new user
        err = db.Debug().Exec(`insert into users(username,email,phone) values(?,?,?)`, req.Data.User, req.Data.Email, req.Data.Phone).Error
        if err !=nil{
          resp.Body =ParseResponse(HttpResponse{Uuid: req.RequestID, Err: err})return resp,nil}
        resp.Body =ParseResponse(HttpResponse{Uuid: req.RequestID, Data:nil})return resp,nil}

Get user by id

  • tạo endpoint trong file serverless:
functions:read:handler: bin/read
    description: get user detail by id
    events:-http:path: /read
          method: get
  • Code implement:
    • Struct nhận request từ client
      type UserDTO struct{
        ID string`json:"userId"`}
    • function get user detail by id
      funcReadUser(ctx context.Context,
        eventReq events.APIGatewayProxyRequest)(Response,error){var(
          req  = RequestBodyAPIGW{}
          resp = Response{
            StatusCode:400,
            IsBase64Encoded:false,
            Headers:map[string]string{"Content-Type":"application/json",},})// get parameter from url
        req.Data.ID = eventReq.QueryStringParameters["id"]// init database,
        db, err := pkg.InitPostgres()if err !=nil{
          resp.Body =ParseResponse(HttpResponse{
            Uuid: req.RequestID,
            Err:  err,})
          resp.StatusCode =500return resp,nil}
        resp.StatusCode =200var user = models.UserModel{}
        err = db.Table("users").Where("id = ?", req.Data.ID).First(&user).Error
        if err !=nil{
          resp.Body =ParseResponse(HttpResponse{Uuid: req.RequestID, Err: err})return resp,nil}
        resp.Body =ParseResponse(HttpResponse{Uuid: req.RequestID, Data: user})return resp,nil}

Get update user

  • tạo endpoint trong file serverless
    functions:
      update:
        handler: bin/update
        description: update user by id
        events:
          - http:
              path: /update
              method: post
    
  • Struct nhận request từ client
    type UserDTO struct{
        ID    int`json:"userId"`
        Email string`json:"email"`
        Phone string`json:"phone"`}
  • Code implement
    • function get update user
      funcUpdateUser(ctx context.Context, eventReq events. APIGatewayProxyRequest)(Response,error){var(
          req  = RequestBodyAPIGW{}
          resp = Response{
            StatusCode:400,
            IsBase64Encoded:false,
            Headers:map[string]string{"Content-Type":"application/json",},})
        err := json.Unmarshal([]byte(eventReq.Body),&req)if err !=nil{
          resp.Body =ParseResponse(HttpResponse{
            Uuid: req.RequestID,
            Err:  err,})return resp,nil}
        db, err := pkg.InitPostgres()if err !=nil{
          resp.Body =ParseResponse(HttpResponse{
            Uuid: req.RequestID,
            Err:  err,})
          resp.StatusCode =500return resp,nil}
        resp.StatusCode =200
        err = db.Exec(`update users set email = ?, phone = ? where id = ?`, req.Data.Email, req.Data.Phone, req.Data.ID).Error
        if err !=nil{
          resp.Body =ParseResponse(HttpResponse{Uuid: req.RequestID, Err: err})return resp,nil}
        resp.Body =ParseResponse(HttpResponse{Uuid: req.RequestID, Data:nil})return resp,nil}

Detele user

  • tạo endpoint trong file serverless
    functions:
      delete:
        handler: bin/delete
        description: delete user by id
        events:
          - http:
              path: /delete
              method: post
    
  • Struct nhận request từ client
    type UserDTO struct{
        ID    int`json:"userId"`}
  • Code implement
    • function get delete user by id
      funcDeleteUser(ctx context.Context, eventReq events.APIGatewayProxyRequest)(Response,error){var(
          req  = RequestBodyAPIGW{}
          resp = Response{
            StatusCode:400,
            IsBase64Encoded:false,
            Headers:map[string]string{"Content-Type":"application/json",},})
        err := json.Unmarshal([]byte(eventReq.Body),&req)if err !=nil{
          resp.Body =ParseResponse(HttpResponse{
            Uuid: req.RequestID,
            Err:  err,})return resp,nil}
        db, err := pkg.InitPostgres()if err !=nil{
          resp.Body =ParseResponse(HttpResponse{
            Uuid: req.RequestID,
            Err:  err,})
          resp.StatusCode =500return resp,nil}
        resp.StatusCode =200var user = models.UserModel{}
        err = db.Debug().Table("users").Delete(&user, req.Data.ID).Error
        if err !=nil{
          resp.Body =ParseResponse(HttpResponse{Uuid: req.RequestID, Err: err})return resp,nil}
        resp.Body =ParseResponse(HttpResponse{Uuid: req.RequestID, Data: req.Data})return resp,nil}

Nguồn: viblo.asia

Bài viết liên quan

WebP là gì? Hướng dẫn cách để chuyển hình ảnh jpg, png qua webp

WebP là gì? WebP là một định dạng ảnh hiện đại, được phát triển bởi Google

Điểm khác biệt giữa IPv4 và IPv6 là gì?

IPv4 và IPv6 là hai phiên bản của hệ thống địa chỉ Giao thức Internet (IP). IP l

Check nameservers của tên miền xem website trỏ đúng chưa

Tìm hiểu cách check nameservers của tên miền để xác định tên miền đó đang dùn

Mình đang dùng Google Domains để check tên miền hàng ngày

Từ khi thông báo dịch vụ Google Domains bỏ mác Beta, mình mới để ý và bắt đầ