ServiceProvider를 살펴보고, 설정을 패키지의 공개 API로서 유지보수하는 방법을 정리합니다. 패키지 개발의 기초를 전제로 하며, 구현 확인에는 laravel/framework의 v13.34.0을 사용했습니다.
배포와 병합은 별개의 처리
publishes()는 복사 원본과 복사 대상을 등록합니다. vendor:publish가 파일을 복사하기 전까지 사용자의 config 디렉터리는 바뀌지 않습니다. 반면 mergeConfigFrom()은 시작 시 설정 저장소를 갱신할 뿐, 파일 자체를 다시 쓰지 않습니다.
register()의 병합으로 기본값이 사용됩니다.
mergeConfigFrom()은 최상위만 병합한다
ServiceProvider::mergeConfigFrom()은 패키지 설정을 먼저, 애플리케이션의 기존 설정을 나중에 전달하여 array_merge()를 실행합니다. 같은 문자열 키에서는 애플리케이션 쪽 값이 우선합니다.
다음은 프레임워크의 병합 처리를 배열만으로 재현한 예입니다.
enabled는 보완되지만, transport는 배열 전체가 교체됩니다. transport.retries는 남지 않습니다. 사용자가 예전 transport 배열을 이미 배포했다면, 같은 배열에 새 키를 추가해도 보완되지 않는다는 점이 중요합니다.
replaceConfigRecursivelyFrom()으로 중첩된 설정 보완하기
Laravel 13의ServiceProvider에는 protected 메서드인 replaceConfigRecursivelyFrom()도 있습니다. 이 메서드는 같은 순서로 array_replace_recursive()를 실행합니다.
중첩된 문자열 키를 개별적으로 덮어쓸 수 있는 설정 API로 만들고 싶다면, 프로바이더의 register()를 다음과 같이 변경하세요. 같은 설정 키에 대해 앞의 mergeConfigFrom()과 함께 사용할 필요는 없습니다.
$defaults와 $overrides를 사용하면 결과는 다음과 같습니다.
replaceConfigRecursivelyFrom()은 이 페이지에서 확인한 Laravel 13 소스 코드에 존재하는 메서드입니다. 공식 패키지 개발 문서에서 소개하는 mergeConfigFrom()과 구분하고, 대응하는 프레임워크 구현을 확인한 뒤 사용하세요.숫자 키 리스트는 전체 교체되지 않는다
재귀적 치환은 “배열을 모두 사용자의 값으로 바꾸는” 처리가 아닙니다. 숫자 키라도 같은 키의 값을 교체하고, 사용자가 지정하지 않은 키는 남겨 둡니다.['slack']만 지정해도 database가 남습니다. 또한 ['channels' => []]를 전달해도 기본 리스트는 비워지지 않습니다. 알림 대상이나 미들웨어처럼 리스트 전체를 지정하는 것이 의미 있는 설정에서는 특히 주의하세요.
이런 설정이 있다면 리스트와 부분적으로 덮어쓸 수 있는 연관 배열을 서로 다른 최상위 키로 나누고 얕은 병합을 사용하는 등, 설정 구조부터 검토하세요. 이미 공개한 패키지에서 병합 방식을 바꾸면 같은 설정 파일이라도 동작이 달라지므로, 단순한 구현 교체로 취급하지 마세요.
설정 캐시에는 병합 후의 값이 저장된다
두 메서드 모두 애플리케이션이CachesConfiguration을 구현하고 configurationIsCached()가 true인 경우에는 병합 처리를 건너뜁니다. 일반적인 Laravel 애플리케이션에서는 설정 캐시가 존재하는 상태의 시작이 여기에 해당합니다.
ConfigCacheCommand는 오래된 설정 캐시를 삭제하고, 새 애플리케이션을 시작해 설정 저장소 전체를 가져옵니다. 그 시작 과정에서 프로바이더의 설정이 병합되고, 결과가 캐시 파일에 저장됩니다. 이후의 시작에서는 LoadConfiguration이 그 값을 읽어 들입니다.
따라서 패키지를 업데이트해 기본값이나 병합 방식이 바뀌어도, 오래된 캐시를 계속 사용하는 애플리케이션에는 반영되지 않습니다. 설정 캐시를 사용하는 배포 환경에서는 업데이트된 코드로 캐시를 다시 생성하세요.
php artisan config:clear를 사용하세요. 캐시 생성 위치를 직접 정하지 말고, Laravel 명령어에 관리를 맡기세요.
설정 변경을 릴리스하기 전 확인 사항
패키지 테스트에서는 배포되지 않은 설정뿐 아니라, 이전 버전에서 남아 있는 설정도 입력으로 다룹니다.- 설정을 배포하지 않아도 필요한 기본값을 가져올 수 있다.
- 오래된 배포 설정에서 사용자의 값이 우선하고, 새 항목이 설계대로 보완된다.
- 중첩된 배열, 숫자 키 리스트, 빈 배열에 대해 덮어쓰기 계약이 바뀌지 않는다.
- 사용하는 애플리케이션에서
config:cache가 성공하고, 캐시를 사용하는 다른 시작에서도 같은 설정이 된다.
관련 페이지
패키지 테스트
서비스 프로바이더를 등록하고 설정과 서비스의 동작을 검증합니다.
버전 호환성 관리
공개 API의 변경을 릴리스 방침과 지속적인 유지보수에 연결합니다.