동적 라우팅
앵귤러에서 동적 라우팅(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 설계 권장
- routerLink와 router.navigate() 병행 사용으로 유연한 UX 구현
'개발 공부 > Angular' 카테고리의 다른 글
| Angular Subject, BehaviorSubject (0) | 2025.07.05 |
|---|---|
| Angular 동적 라우팅 vs 쿼리 파라미터 (0) | 2025.06.01 |
| RxJS 연산자 debounceTime, switchMap, mergeMap (1) | 2025.05.29 |
| 컴포넌트 인클루전 방식 vs 라우트 분리 방식 (0) | 2025.05.27 |
| Angular computed() (0) | 2025.05.26 |