iT邦幫忙

2023 iThome 鐵人賽

DAY 12
0

今天我們先定義好資料夾結構,然後寫一些框和範例起來,首先先建立下面的資料夾路徑&檔案

https://ithelp.ithome.com.tw/upload/images/20230927/20115990Vm34se4jpY.png

當收到Linebot的請求後,我們的應用會在Router層接收並處理它,根據request的不同,Router層能夠調用不同的服務(service)來進行處理。Service的負責統一調用Adapter層和Domain層。Adapter負責與外部資源進行互動和操作,而Domain層則專注於處理業務邏輯。

  1. 我們把前幾天寫的dynamodb放到adapter下,然後在dynamodb下建立interface.go,把我們寫好想要對外(自己的service)提供的function放進去

    // interface.go
    package dynamodb
    
    import (
    	"github.com/aws/aws-sdk-go-v2/service/dynamodb"
    	"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
    )
    
    type DynamodbI interface {
    	CreateGoogleOAuthTable() (*types.TableDescription, error)
    	AddGoogleOAuthToken(tok GoogleOAuthToken) error
    	TxUpdateGoogleOAuthToken(tok GoogleOAuthToken) (*dynamodb.TransactWriteItemsOutput, error)
    	GetGoogleOAuthToken(line_userid string) (GoogleOAuthToken, error)
    }
    
  2. 接著我們在app/service下,建立一個Sample service資料夾,和interface.go,sample_service.go,service.go三個檔案

    https://ithelp.ithome.com.tw/upload/images/20230927/20115990uY9aTwxHBS.png

  3. 假設我們這個service想要使用上面dynamodb提供的GetGoogleOAuthToken(),我們就在interface.go像下面這樣加上去

    // interface.go
    package sample
    
    import "github.com/onepiece010938/Line2GoogleDriveBot/internal/adapter/dynamodb"
    
    type SampleServiceDynamodbI interface {
    	GetGoogleOAuthToken(line_userid string) (dynamodb.GoogleOAuthToken, error)
    }
    
  4. 接著service.go,創建一個 SampleService 服務,並透過構造函數 NewSampleService() 將其所依賴的 SampleServiceDynamodb 實例注入到服務中。

    package sample
    
    import "context"
    
    type SampleService struct {
    	sampleServiceDynamodb SampleServiceDynamodbI
    }
    // SampleServiceParam 是用於建構 SampleService 的參數結構體
    type SampleServiceParam struct {
    	SampleServiceDynamodb SampleServiceDynamodbI
    }
    
    // 建立並回傳一個新的 SampleService 實例
    // param: SampleService 的建構參數,包含一個 SampleServiceDynamodb 實例
    func NewSampleService(_ context.Context, param SampleServiceParam) *SampleService {
    	return &SampleService{
    		sampleServiceDynamodb: param.SampleServiceDynamodb,
    	}
    }
    

    在測試or要替換掉Dynamodb的時候,只需更改NewSampleService的參數就好,而不用去動到SampleService本身的程式。

  5. 最後sample_service.go就是我們服務本身提供的function,這邊寫一個簡單的範例,直接去調用注入進來的GetGoogleOAuthToken,輸入lineID查詢取得token後回傳PK,也就是輸入lineID test1234 如果有查到token會回傳LINE#test1234

    package sample
    
    import (
    	"context"
    	"fmt"
    )
    
    func (s *SampleService) Sample(ctx context.Context, lineID string) (string, error) {
    	t, err := s.sampleServiceDynamodb.GetGoogleOAuthToken(lineID)
    	if err != nil {
    		return "", err
    	}
    	fmt.Println(t)
    	return t.PK, nil
    }
    
  6. 最後的最後到application.go,他負責把所有的service拉起來。因此後續有新的service時,我們也會放到Application這個srtuct裡,同時還有一個*linebot.Client供整個application來調用linebot。

    package app
    
    import (
    	"context"
    
    	"github.com/line/line-bot-sdk-go/linebot"
    	"github.com/onepiece010938/Line2GoogleDriveBot/internal/adapter/dynamodb"
    
    	serviceSample "github.com/onepiece010938/Line2GoogleDriveBot/internal/app/service/sample"
    )
    
    type Application struct {
    	SampleService *serviceSample.SampleService
    	LineBotClient *linebot.Client
    }
    
    // 建立並回傳一個新的 Application 實例
    // dynamodb: 輸入實現了 dynamodb.DynamodbI interface的對象
    func NewApplication(ctx context.Context, dynamodb dynamodb.DynamodbI, lineBotClient *linebot.Client) *Application {
    
    	app := &Application{
    		LineBotClient: lineBotClient,
    		SampleService: serviceSample.NewSampleService(ctx, serviceSample.SampleServiceParam{
    			SampleServiceDynamodb: dynamodb, // 在這邊傳入DynamoDB的instance
    		}),
    	}
    	return app
    }
    

這樣今天就完成了應用層的建立,並寫了一個sample service當作範例,明天我們來寫Router層的部分,那我們明天見囉~


上一篇
Day11 Sever"啟動" - Gin + ( Lambda or Ngrok ) 01
下一篇
Day13 Sever"啟動" - Gin + ( Lambda or Ngrok ) 03
系列文
Golang LineBot X GoogleDrive:LINE有各種限制!? 那就丟上Drive吧!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言