Laravel 주니어 프레임워크 기술면접
새 면접Q. Laravel Artisan CLI는 무엇이며, 주요 용도는 무엇인가요? 개발 과정에서 자주 사용하는 Artisan 명령어 3가지를 예시로 들어 설명해주세요.
Laravel의 명령줄 인터페이스 도구로, 반복적인 작업을 자동화하는 데 사용됩니다.
Artisan은 Laravel에 포함된 명령줄 인터페이스(CLI) 도구로, 개발 과정에서 반복적인 작업을 자동화하고 생산성을 높이는 데 사용됩니다. php artisan make:controller 명령어로 컨트롤러를 자동 생성할 수 있고, php artisan migrate로 데이터베이스 마이그레이션을 실행할 수 있습니다. php artisan tinker는 Laravel 애플리케이션과 상호작용할 수 있는 REPL 환경을 제공하여 코드를 테스트하거나 데이터를 조작할 수 있습니다. 이 외에도 큐 작업 실행, 캐시 클리어, 스케줄러 실행 등 다양한 명령어를 제공합니다.
- • Laravel의 CLI 도구
- • 반복 작업 자동화
- • make 명령어로 파일 생성
- • migrate로 DB 스키마 관리
- • tinker로 대화형 환경 제공
개발 중 컨트롤러, 모델, 마이그레이션 파일을 빠르게 생성하고, 배포 시 마이그레이션과 캐시 최적화를 수행할 때 사용됩니다.
커스텀 Artisan 명령어를 만들어야 하는 경우는 언제이며, 어떻게 생성하나요?
Q. Laravel Eloquent에서 Mass Assignment는 무엇이며, fillable과 guarded 속성의 차이점을 설명해주세요. Mass Assignment 취약점은 왜 발생하며 어떻게 방지할 수 있나요?
대량 할당은 배열로 여러 속성을 한 번에 설정하는 기능이며, 보안을 위해 허용할 필드를 명시해야 합니다.
Mass Assignment는 배열 형태의 데이터를 모델의 create나 update 메서드에 전달하여 여러 속성을 한 번에 설정하는 기능입니다. fillable 속성은 화이트리스트 방식으로 대량 할당이 허용되는 필드를 명시하고, guarded는 블랙리스트 방식으로 대량 할당이 금지되는 필드를 명시합니다. Mass Assignment 취약점은 사용자가 요청에 is_admin 같은 민감한 필드를 포함시켜 권한을 상승시킬 수 있는 보안 문제입니다. 이를 방지하려면 모델에 fillable 또는 guarded를 반드시 설정하고, 컨트롤러에서 $request->only()나 $request->validated()로 허용된 필드만 전달해야 합니다.
- • 배열로 여러 속성 한 번에 설정
- • fillable은 화이트리스트
- • guarded는 블랙리스트
- • 권한 상승 취약점 방지
- • 허용된 필드만 전달
사용자 등록 API에서 요청 데이터를 모델에 저장할 때, 의도하지 않은 필드(role, is_verified 등)가 변경되지 않도록 보호합니다.
fillable과 guarded를 동시에 설정하면 어떻게 동작하나요?
Q. Laravel Form Request 클래스의 authorize 메서드와 rules 메서드는 각각 어떤 역할을 하나요? 이 두 메서드가 실행되는 순서와 실패 시 어떤 응답이 반환되는지 설명해주세요.
authorize는 권한 검증, rules는 입력 검증을 담당하며, 실행 순서가 중요합니다.
Form Request 클래스에서 authorize 메서드는 요청자가 해당 작업을 수행할 권한이 있는지 검증하고, rules 메서드는 요청 데이터의 유효성 검증 규칙을 정의합니다. 실행 순서는 authorize가 먼저 실행되고, 권한이 있으면 rules 검증이 진행됩니다. authorize에서 false를 반환하면 403 Forbidden 응답이 반환되고, rules 검증 실패 시에는 422 Unprocessable Entity 응답과 함께 검증 오류 메시지가 JSON 형태로 반환됩니다. 이를 통해 권한 검증과 입력 검증을 컨트롤러에서 분리하여 코드의 가독성과 재사용성을 높일 수 있습니다.
- • authorize는 권한 검증
- • rules는 입력 검증
- • authorize가 먼저 실행
- • 403 vs 422 응답
- • 컨트롤러 코드 분리
게시글 수정 API에서 작성자 본인만 수정할 수 있도록 권한을 검증하고, 동시에 제목과 내용의 유효성을 검증할 때 사용됩니다.
Form Request에서 검증 실패 시 반환되는 응답 형식을 커스터마이징하려면 어떻게 해야 하나요?
Q. Laravel Eloquent에서 Eager Loading과 Lazy Loading의 차이점을 설명하고, 각각 언제 사용해야 하는지 설명해주세요. with 메서드를 사용하는 이유는 무엇인가요?
관계 데이터를 언제 로드하는지에 따라 쿼리 수와 성능이 달라집니다.
Lazy Loading은 관계 데이터에 접근할 때 자동으로 추가 쿼리를 실행하여 데이터를 가져오는 방식이고, Eager Loading은 with 메서드를 사용해 초기 쿼리에서 관계 데이터를 미리 함께 가져오는 방식입니다. Lazy Loading은 관계 데이터가 필요하지 않을 수도 있는 경우에 적합하지만, N+1 쿼리 문제를 발생시킬 수 있습니다. Eager Loading은 관계 데이터가 항상 필요한 경우 사용하며, with 메서드로 한 번의 추가 쿼리로 모든 관계 데이터를 가져와 성능을 최적화합니다. 예를 들어 게시글 목록과 작성자 정보를 함께 조회할 때 Post::with('user')->get()을 사용하면 2개의 쿼리로 모든 데이터를 가져올 수 있습니다.
- • Lazy Loading은 접근 시 로드
- • Eager Loading은 미리 로드
- • N+1 문제 방지
- • with 메서드 사용
- • 쿼리 수 최적화
게시글 목록 API에서 각 게시글의 작성자 정보를 함께 반환할 때, N+1 쿼리를 방지하기 위해 Eager Loading을 사용합니다.
이미 조회한 모델에 대해 나중에 관계를 Eager Loading하려면 어떤 메서드를 사용해야 하나요?
Q. Laravel의 config 디렉토리와 .env 파일의 역할 차이를 설명하고, config 파일에서 env 함수를 사용하는 이유는 무엇인가요? 설정 값을 가져올 때 config 함수를 사용하는 것이 권장되는 이유도 함께 설명해주세요.
환경별 설정과 애플리케이션 설정을 분리하여 관리하는 구조입니다.
.env 파일은 환경별로 다른 값(데이터베이스 접속 정보, API 키 등)을 저장하는 환경 변수 파일이고, config 디렉토리는 애플리케이션의 전체 설정 구조를 정의하는 PHP 파일들입니다. config 파일에서 env 함수를 사용하면 환경 변수를 읽어와 설정 값으로 사용할 수 있어, 개발/스테이징/프로덕션 환경마다 다른 값을 적용할 수 있습니다. 코드에서 직접 env 함수를 호출하면 config cache 사용 시 null이 반환되므로, config 함수를 사용해 캐시된 설정 값을 가져오는 것이 권장됩니다. 이를 통해 설정 관리의 일관성을 유지하고 성능을 최적화할 수 있습니다.
- • .env는 환경 변수
- • config는 설정 구조
- • 환경별 다른 값 적용
- • config cache 고려
- • config 함수 사용 권장
개발 환경에서는 로컬 DB를 사용하고 프로덕션에서는 RDS를 사용하도록 .env 파일만 변경하여 배포합니다.
프로덕션 환경에서 php artisan config:cache를 실행하는 이유는 무엇인가요?
Q. Laravel에서 HTTP 요청이 들어왔을 때 Kernel의 역할은 무엇이며, Global Middleware와 Route Middleware의 차이점을 설명해주세요. 미들웨어 우선순위는 어떻게 결정되나요?
Kernel은 요청 처리의 중심이며, 미들웨어를 관리하고 실행 순서를 제어합니다.
Kernel(app/Http/Kernel.php)은 HTTP 요청의 진입점으로, 모든 요청이 애플리케이션에 도달하기 전에 거쳐야 하는 미들웨어를 정의하고 관리합니다. Global Middleware는 $middleware 배열에 정의되며 모든 HTTP 요청에 적용되고, Route Middleware는 $routeMiddleware 배열에 정의되며 특정 라우트나 라우트 그룹에만 선택적으로 적용됩니다. 미들웨어 실행 순서는 Kernel의 $middlewarePriority 배열로 제어할 수 있으며, 인증 미들웨어가 세션 미들웨어보다 먼저 실행되는 등 논리적 순서를 보장합니다. Global Middleware는 정의된 순서대로 실행되고, Route Middleware는 라우트에 지정된 순서와 우선순위 설정에 따라 실행됩니다.
- • Kernel은 미들웨어 관리
- • Global은 모든 요청 적용
- • Route는 선택적 적용
- • middlewarePriority로 순서 제어
- • 논리적 실행 순서 보장
API 인증, CORS 처리, 로깅 등을 미들웨어로 구현하여 모든 요청에 일관되게 적용하거나 특정 라우트에만 선택적으로 적용합니다.
미들웨어에서 $next($request) 호출 전후에 코드를 작성하는 것의 차이는 무엇인가요?
Q. Laravel의 Seeder와 Factory의 역할을 각각 설명하고, 두 기능을 함께 사용하는 이유는 무엇인가요? 개발 과정에서 Seeder를 사용하는 장점을 설명해주세요.
Factory는 모델 인스턴스 생성 로직을 정의하고, Seeder는 실제 데이터베이스에 데이터를 삽입합니다.
Factory는 모델의 더미 데이터를 생성하는 청사진을 정의하는 클래스로, Faker 라이브러리를 활용해 랜덤하지만 현실적인 테스트 데이터를 만듭니다. Seeder는 Factory를 사용하거나 직접 데이터를 정의하여 실제 데이터베이스에 초기 데이터를 삽입하는 클래스입니다. Factory로 데이터 생성 로직을 재사용 가능하게 정의하고, Seeder에서 필요한 만큼 호출하여 일관된 테스트 환경을 구축할 수 있습니다. 개발 과정에서 Seeder를 사용하면 데이터베이스를 초기화하고 테스트 데이터를 빠르게 생성할 수 있어, 기능 개발과 테스트가 용이해집니다. php artisan db:seed 명령어로 언제든 데이터를 재생성할 수 있습니다.
- • Factory는 데이터 생성 청사진
- • Seeder는 DB 삽입
- • Faker로 현실적인 데이터
- • 재사용 가능한 구조
- • 테스트 환경 구축
새로운 기능 개발 시 테스트용 사용자, 게시글, 댓글 데이터를 빠르게 생성하여 UI와 비즈니스 로직을 검증합니다.
Factory에서 상태(state)를 정의하는 이유는 무엇이며 어떻게 사용하나요?
Q. Laravel API Resource의 역할과 사용 목적을 설명하고, Eloquent 모델을 직접 반환하는 것과 비교했을 때 어떤 장점이 있나요? toArray 메서드를 오버라이드하는 이유도 함께 설명해주세요.
API 응답 구조를 제어하고 표현 계층을 분리하는 데 사용됩니다.
API Resource는 Eloquent 모델을 JSON 응답으로 변환할 때 출력 형식을 제어하는 변환 계층(Transformation Layer)입니다. 모델을 직접 반환하면 모든 속성이 노출되지만, Resource를 사용하면 필요한 필드만 선택하고, 형식을 변경하고, 관계 데이터를 조건부로 포함할 수 있습니다. toArray 메서드를 오버라이드하여 반환할 데이터 구조를 명시적으로 정의하며, 비밀번호 같은 민감한 정보를 제외하거나 created_at을 포맷팅하는 등의 작업을 수행합니다. Resource를 사용하면 API 응답 스펙이 변경될 때 모델이나 컨트롤러를 수정하지 않고 Resource만 수정하면 되어 유지보수성이 향상됩니다. ResourceCollection을 사용하면 페이지네이션된 응답도 일관되게 처리할 수 있습니다.
- • 응답 형식 제어
- • 민감 정보 제외
- • 표현 계층 분리
- • toArray로 구조 정의
- • 유지보수성 향상
사용자 목록 API에서 비밀번호와 토큰은 제외하고, 프로필 이미지 URL은 전체 경로로 변환하여 클라이언트에 일관된 형식으로 제공합니다.
API Resource에서 조건부로 필드를 포함하거나 제외하려면 어떤 메서드를 사용해야 하나요?
Q. Laravel에서 API Rate Limiting은 무엇이며, 왜 필요한가요? ThrottleRequests 미들웨어를 사용하여 Rate Limiting을 적용하는 방법과, 제한 횟수를 초과했을 때 어떤 응답이 반환되는지 설명해주세요.
API 남용을 방지하고 서버 자원을 보호하기 위해 요청 횟수를 제한합니다.
Rate Limiting은 특정 시간 동안 클라이언트가 보낼 수 있는 API 요청 횟수를 제한하여 서버 과부하와 악의적인 공격을 방지하는 기능입니다. Laravel의 ThrottleRequests 미들웨어를 라우트에 적용하면 IP 주소나 인증된 사용자 기준으로 요청 횟수를 제한할 수 있습니다. 예를 들어 throttle:60,1을 지정하면 1분에 60회로 제한되며, 이를 초과하면 429 Too Many Requests 응답이 반환됩니다. 응답 헤더에는 X-RateLimit-Limit, X-RateLimit-Remaining, Retry-After 정보가 포함되어 클라이언트가 제한 상태를 파악할 수 있습니다. RouteServiceProvider에서 RateLimiter 파사드로 커스텀 Rate Limiter를 정의하여 사용자 등급별로 다른 제한을 적용할 수도 있습니다.
- • 요청 횟수 제한
- • 서버 보호
- • ThrottleRequests 미들웨어
- • 429 응답
- • RateLimiter 커스터마이징
공개 API에서 무료 사용자는 시간당 100회, 유료 사용자는 1000회로 제한하여 서비스 안정성을 유지하고 과금 모델을 구현합니다.
인증된 사용자와 비인증 사용자에게 서로 다른 Rate Limit을 적용하려면 어떻게 해야 하나요?
Q. Laravel Eloquent에서 Dynamic Scope는 무엇이며, Local Scope와 어떤 차이가 있나요? Dynamic Scope를 사용하면 어떤 장점이 있는지 예시와 함께 설명해주세요.
Dynamic Scope는 매개변수를 받아 유연하게 쿼리를 구성할 수 있는 Scope입니다.
Dynamic Scope는 매개변수를 받을 수 있는 Local Scope로, 쿼리 조건을 동적으로 변경할 수 있습니다. Local Scope는 고정된 조건을 캡슐화하지만, Dynamic Scope는 scopeMethodName($query, $parameter) 형태로 정의하여 호출 시 인자를 전달할 수 있습니다. 예를 들어 scopeOfType($query, $type) 메서드를 정의하면 Post::ofType('news')->get()처럼 타입을 동적으로 지정하여 조회할 수 있습니다. 이를 통해 하나의 Scope 메서드로 다양한 조건을 처리할 수 있어 코드 중복을 줄이고 재사용성을 높입니다. 여러 매개변수를 받을 수도 있어, scopePublishedBetween($query, $startDate, $endDate) 같은 복잡한 조건도 깔끔하게 표현할 수 있습니다.
- • 매개변수를 받는 Scope
- • 동적 조건 처리
- • 코드 재사용성
- • 여러 인자 전달 가능
- • 쿼리 가독성 향상
상품 필터링 API에서 카테고리, 가격 범위, 재고 상태 등을 동적으로 조합하여 검색할 때 각 조건을 Dynamic Scope로 구현합니다.
여러 개의 Dynamic Scope를 체이닝하여 사용할 때 주의할 점은 무엇인가요?
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!