초기에 Spring Webflux 로 리액티브 프로그래밍을 할 때 많은 도움을 받았던 내용을 공유합니다. 유지보수를 위해서는 읽기 쉬운 코드를 작성해야하는게 정석이지만 이는 생각보다 쉽지 않고 많
초기에 Spring Webflux 로 리액티브 프로그래밍을 할 때 많은 도움을 받았던 내용을 공유합니다. 유지보수를 위해서는 읽기 쉬운 코드를 작성해야하는게 정석이지만 이는 생각보다 쉽지 않고 많은 고민을 필요로 합니다. 리액티브 프로그래밍의 경우 기존에 일반적으로 작성하는 코드와는 완전히 다른 패러다임을 강제하고 있다보니 기존에 정립한 규칙이나 노하우를 완전히 바꿔야 했고 이를 제대로 잡지 않으면 유지보수를 포기해야 할 수도 있습니다. 제가 처음 리액티브 프로그래밍을 시작했을 때는 아직 리액티브 프로그래밍이 시작된지 얼마 안된 시기라 클린코드나 이펙티브 자바와 같은 이정표가 없었습니다. 한참동안 이에 대해 고민하던 중 이 블로그 글을 접하게 되었고 많은 부분에서 공감하여 진행하던 프로젝트에 접목했습니다. 그 결과 지금까지 크게 문제없이 잘 유지되고 있습니다. 클린 리액티브 코드에서 가장 중요하다고 생각되는 항목을 몇가지 나열해보자면 다음과 같습니다. ✅️ 연산자를 중심으로 코드를 작성 연산자(Operator)는 리액티브 프로그래밍에서 사용 가능한 연산의 기본 단위입니다. 그래서 코드를 작성할 때는 연산자를 중심으로 왼쪽에서 오른쪽, 위에서 아래 방향으로 마치 책을 읽는 것처럼 작성하는 것이 다른 사람들이 제일 이해하기 편합니다. ✅️ map, flatMap 등의 함수는 최대한 간결하게 많은 사람들이 제일 자주 사용하는 map 과 flatMap 의 함수 내부에 장황한 비즈니스 로직을 작성하곤 합니다. 그치만 이는 코드의 흐름을 끊기게 해 가독성에 별로 좋지 않습니다. 중요한 큰 흐름은 연산자의 체인과 그 인자만으로 읽어낼 수 있어야 하기 때문에 장황한 로직은 외부 함수로 빼내도록 하는게 좋습니다. ✅️ Mono, Flux의 구분이 필요한 곳은 변수명에 명시하기 일반적으로 모든 Publisher 타입에 Mono나 Flux 를 변수 명에 넣어줄 필요는 없습니다. 하지만 해당 변수가 Publisher 임을 명시적으로 하고 싶거나 Flux 와 Mono 사이에 연산을 수행할 때는 변수명에 Flux 나 Mono 를 포함 시키는게 좋습니다. 특히 Flux 와 Mono 간의 연산이 필요할 때는 변수명을 Mono 나 Flux 를 붙여서 서로 다른 타입과 연산을 수행함을 알 수 있게 합니다. ✅️ 명시적인 subscribe() 호출은 신중하게 리액티브 체인 내부에서 subscibe() 를 호출하는 것은 되도록 피해야합니다. 이는 엔지니어가 인식하지 못하는 사이 장기간 돌아가는 스레드를 만들 가능성이 있습니다. 리액티브 프로그래밍은 subscribe() 가 반환하는 Disposable 타입을 사용해 처리량을 조절할 수 있도록 해야합니다. ✅️ flatMap 의 형제/자매(?) 연산자를 잘 알자 리액티브에서 이야기 하는 성능의 향상, 즉 높은 동시성은 거의 대부분은 flatMap 을 중심으로 이루어집니다. 그래서 데이터 흐름을 조절하는 delayElement 등을 flatMap 주변에서 사용할 때는 유의해야하고 자매 연산자인 flatMapSequential, concatMap 등과의 차이점을 확실히 파악하여 필요할 때에 쓸 수 있도록 해야합니다.