본문 바로가기

Programming Language/golang

Redis-go를 interface화 하여 사용하기

golang에서 Redis를 사용할 때는 보통 go-redis 라이브러리를 많이 사용합니다. 이 때, 바로 메서드를 사용하기 보다는 내부 비즈니스 로직이 포함된 RedisClient 인터페이스를 만들어 사용하곤 하는데요. 아래는 그 예시 입니다.

 

redis.go

package main

import (
    "context"
    "fmt"
    "github.com/go-redis/redis/v8" // go-redis import
)

// RedisClientInterface 인터페이스 정의
type RedisClientInterface interface {
    Set(key string, value interface{}) error
    Get(key string) (string, error)
}

// RedisClient 구조체 정의
type RedisClient struct {
    client *redis.Client
}

// NewRedisClient 함수는 RedisClient 인스턴스를 초기화합니다.
func NewRedisClient(addr string) *RedisClient {
    return &RedisClient{
        client: redis.NewClient(&redis.Options{
            Addr: addr, // Redis 서버 주소
        }),
    }
}

// Get 메서드는 주어진 키에 대한 값을 Redis에서 검색합니다.
func (c *RedisClient) Get(key string) (string, error) {
    ctx := context.Background()
    result, err := c.client.Get(ctx, key).Result()
    if err != nil {
        return "", err
    }
    return result, nil
}

 

main.go

func main() {
    // RedisClient 인스턴스 생성
    redisClient := NewRedisClient("localhost:6379")

    // Set 예시
    err := redisClient.Set("key", "value")
    if err != nil {
        fmt.Println("Set error:", err)
        return
    }

    // Get 예시
    result, err := redisClient.Get("key")
    if err != nil {
        fmt.Println("Get error:", err)
        return
    }

    fmt.Println("Get result:", result)
}

 

위와 같은 방식은 일반적으로 많이 사용되는 Struct 선언 구문입니다. 하지만, Testify와 같은 도구로 테스트를 할 때는 RedisClient를 Interface화 해야하는데, 이 때는 RedisClientInterface를 따로 정의해야 합니다. 아래는 그 예시입니다.

 

// RedisClientInterface 정의
type RedisClientInterface interface {
    Get(key string) (string, error)
}

 

단순히 위와 같이 정의만 하더라도 interface를 사용할 수 있습니다. 다만, main.go에서 사용할 때는 RedisClient를 파라미터로 받되, 형을 RedisClientInterface로 받아야만 인터페이스로 사용할 수 있습니다. 아래는 그 예시입니다.

 

// CacheOperation 함수는 RedisClientInterface를 사용하여 캐시 작업을 수행합니다.
func CacheOperation(redisClientInterface를 RedisClientInterface, key string, value string) error {
    if err := redisClientInterface를.Set(key, value); err != nil {
        return fmt.Errorf("failed to set value: %w", err)
    }
    return nil
}

func main() {
    // RedisClient 인스턴스 생성
    redisClient := NewRedisClient("localhost:6379")

    // CacheOperation 함수를 사용하여 캐시 작업 수행
    key := "sampleKey"
    value := "sampleValue"
    if err := CacheOperation(redisClient, key, value); err != nil {
        fmt.Println("Cache operation error:", err)
    }
}

 

위와 같이 CachOperation은 RedisClientInterface를 받아서 사용하게 됩니다. 이렇게 사용할 경우, 상위 레벨 로직으로 부터 분리하고 코드의 유연성과 테스트의 용이성이 향상될 수 있습니다.

 

 

반응형