본문 바로가기

개발 공부/Angular

앵귤러 동적 라우팅(Dynamic Routing)

동적 라우팅

앵귤러에서 동적 라우팅(Dynamic Routing)은 URL 경로의 일부를 동적으로 설정할 수 있도록 해주는 기능입니다.

예를 들어 /user/123, /user/456처럼 유저의 ID에 따라 URL이 달라지는 경우, 해당 경로의 일부인 123, 456이 동적으로 바뀌는 부분입니다.

{ path: 'user/:id', component: UserDetailComponent }
  • 위와 같은 라우팅 설정을 통해 :id가 실제 URL 상에서 다양한 값으로 매핑됩니다.

 

예시 URL

/user/1234
/user/john-doe

 


Path Parameter vs Query Parameter 비교

유형 예시 URL접근 방법
Path Parameter /user/123 ActivatedRoute.paramMap
Query Parameter /user/123?lang=ko ActivatedRoute.queryParamMap
  • 실무에서는 path parameter는 리소스 식별용, query parameter는 필터링이나 정렬 등에 자주 활용합니다.

 


설정 방법

app-routing.module.ts 예시

const routes: Routes = [
  { path: '', redirectTo: 'products', pathMatch: 'full' },
  { path: 'products', component: ProductListComponent },
  { path: 'product/:id', component: ProductDetailComponent },
];

 

 

컴포넌트에서 파라미터 읽기

1. snapshot 방식 (동기)

ngOnInit(): void {
  const id = this.route.snapshot.paramMap.get('id');
}

 

2. observable 방식 (비동기)

ngOnInit(): void {
  this.route.paramMap.subscribe(params => {
    const id = params.get('id');
    this.fetchProduct(id!);
  });
}
  • 비동기 방식은 같은 컴포넌트를 재사용할 때 라우트가 바뀌어도 다시 호출되므로 더 유연합니다.

 

예제: 상품 상세 페이지

서비스

@Injectable({ providedIn: 'root' })
export class ProductService {
  constructor(private http: HttpClient) {}

  getProductById(id: string): Observable<Product> {
    return this.http.get<Product>(`/api/products/${id}`);
  }
}

컴포넌트

@Component({ ... })
export class ProductDetailComponent implements OnInit {
  product$!: Observable<Product>;

  constructor(
    private route: ActivatedRoute,
    private productService: ProductService
  ) {}

  ngOnInit(): void {
    this.product$ = this.route.paramMap.pipe(
      map(params => params.get('id')!),
      switchMap(id => this.productService.getProductById(id))
    );
  }
}

템플릿

<ng-container *ngIf="product$ | async as product">
  <h2>{{ product.name }}</h2>
  <p>{{ product.description }}</p>
</ng-container>

 


라우터 링크 사용

<a [routerLink]="['/product', product.id]">View Details</a>
  • 또는 코드에서 직접 이동
this.router.navigate(['/product', productId], {
  queryParams: { lang: 'ko' }
});

 

 


가드 + 동적 라우팅

{ path: 'user/:id', component: UserComponent, canActivate: [AuthGuard] }
  • 사용자가 해당 경로에 접근 가능한지 사전에 체크 가능합니다.

 


Lazy Loading + 중첩 라우트

const routes: Routes = [
  {
    path: 'admin',
    loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule)
  }
];

 

 

AdminModule 내부에서는:

{ path: 'users/:id', component: AdminUserComponent }

 

 


유의할 점 

  • paramMap.get()null이 될 수 있으므로 방어 코드 필요
  • switchMap을 사용해 기존 요청 취소 처리
  • takeUntil, AsyncPipe로 메모리 누수 방지
  • SEO를 고려해 slug 기반 URL 설계 권장
  • routerLinkrouter.navigate() 병행 사용으로 유연한 UX 구현