[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

7 Cách Tăng Tốc Ứng Dụng React Hiệu Quả Mà Bạn Có Thể Làm Ngay

React là một thư viện JavaScript phổ biến trong việc xây dựng giao diện người d

Trung Quốc “thả quân bài tẩy”: hàng loạt robot hình người!

MỘT CUỘC CÁCH MẠNG ROBOT ĐANG HÌNH THÀNH Ở TRUNG QUỐC Thượng Hải, ngày 13/5 –

9 Mẹo lập trình Web “ẩn mình” giúp tiết kiệm hàng giờ đồng hồ

Hầu hết các lập trình viên (kể cả những người giỏi) đều tốn thời gian x

Can GPT-4o Generate Images? All You Need to Know about GPT-4o-image

OpenAI‘s GPT-4o, introduced on March 25, 2025, has revolutionized the way we create visual con