본문 바로가기

회고/TIL

Sequelize - Scope

Scope

말 뜻 그대로 '범위' 에 대한 개념으로 보면 될 것 같다. 나는 typescript 관련 프로젝트를 하며 ORM으로 sequelize를 사용했는데, 사용을 하다보니 Repository Layer 에서 늘 include로 연계된 모델의 데이터들을 JOIN 해오는 것이 뭔가 지저분해 보였었다. 해서 관련된 내용이 있지 않을까 하고 공식문서를 찾아보던 중, Scope 라는 개념을 접하게 되었다.

 

먼저 아래 코드를 보자.

 

@DefaultScope(()=>({
    attributes: ['date','time'],
}))
@Scopes(()=>({
    full : {
        attributes: ['date','time'],
        include : [
            {
                model : Show,
            },
            {
                model : Seat,
                as : 'seats',
                attributes : ['id','seatNumber','grade','price'],
                where:{
                    isBooked:false
                }
            }
        ]
    },
    seat : {
        attributes: ['time'],
        include : {
            model : Seat,
            as : 'seats',
            attributes : ['id','seatNumber','grade','price'],
            where:{
                isBooked:false
            }
        }
    }
}))
@Table({timestamps:false})
export default class Timetable extends Model<TimetableAttributes,TimetableCreationAttributes>{
    @PrimaryKey
    @AllowNull(false)
    @AutoIncrement
    @Column(DataType.INTEGER)
    id! : number;

    @AllowNull(false)
    @Column(DataType.STRING)
    date! : string;

    @AllowNull(false)
    @Column(DataType.STRING)
    time! : string;

    @AllowNull(false)
    @Column(DataType.BOOLEAN)
    isFilled! : boolean;

    @ForeignKey(()=>Show)
    @Column(DataType.INTEGER)
    showId! : number;

    @BelongsTo(()=>Show)
    show! : Show;

    @HasMany(()=>Seat)
    seats! : Seat[];
}

테이블로 정의된 Timetable 위에 보면 데코레이터로 DefaultScope 와 Scope 두가지를 확인할 수 있을것이다.

 

예상할수있다시피, DefaultScope 같은 경우 Repository Layer 에서 find 메서드를 활용할 때 아무 값을 주지 않으면 기본적으로 실행되는 범위이다. 난 기본적으로 attribute를 'date', 'time' 을 반환하게끔 해주었으니, 실제 반환값에서는 두가지 필드만 반환하는것을 확인할수 있었다.

 

그다음 Scope의 데코레이터를 살펴보게 되면 두가지 값이 존재한다. full 과 seat. full 같은 경우 연계된 테이블 Show와 Seat 모두를 불러와 보여주는 범위이고, seat 같은 경우 Seat 만 불러와 보여주는 범위이다.

 

이처럼 Scope를 정해주게 되면 내가 find 메서드를 활용하려 할때마다 일일히 include 를 활용해 주지 않아도 되서 좀더 코드가 간결해지는 효과를 볼 수 있었고, 또한 유지보수 적으로도 좋다는 걸 느꼈다. 내가 find 메서드를 쓸때 원하는 범위에 대한 수정이 필요할 경우 모델에 와서 해당 Scope만 수정해주면 전체적으로 변경이 될 수 있다는 이점이 존재했다.

 

🔥 정리

Scope를 사용할경우, 코드의 유지보수성을 증가시킬 수 있으며, 범위에 대한 고민을 여러번 할 필요없이 한번에 처리가 가능하단 이점을 챙길 수 있다.
Scope 를 활용하여 현 테이블에서 연계된 테이블들에 대해
어느 범위까지 불러와 보여줄 것인지 정해줄 수 있다는것.

'회고 > TIL' 카테고리의 다른 글

Postgres - Datatype  (0) 2023.08.21
Redis - cache  (0) 2023.08.19
Typescript - Generic  (0) 2023.07.28
2023 - 07 - 05 TIL  (0) 2023.07.05
2023 - 07 - 04 TIL  (0) 2023.07.04