[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

Thay đổi Package Name của Android Studio dể dàng với plugin APR

Nếu bạn đang gặp khó khăn hoặc bế tắc trong việc thay đổi package name trong And

Lỗi không Update Meta_Value Khi thay thế hình ảnh cũ bằng hình ảnh mới trong WordPress

Mã dưới đây hoạt động tốt có 1 lỗi không update được postmeta ” meta_key=

Bài 1 – React Native DevOps các khái niệm và các cài đặt căn bản

Hướng dẫn setup jenkins agent để bắt đầu build mobile bằng jenkins cho devloper an t

Chuyển đổi từ monolith sang microservices qua ví dụ

1. Why microservices? Microservices là kiến trúc hệ thống phần mềm hướng dịch vụ,