안녕하세요, 카카오스타일 지그재그 전시BE파트 밀리입니다. 전시 개발자로서 혹시 이런 하루를 보내고 있나요? if문은 퇴근을 안 해요. 켜는 것도 배포, 끄는 것도 배포예요. 바쁘면 지난 이벤트 분기가 다음 이벤트 때까지 코드에 남아 있어요.ACCENT_400이랑 KEY_COLOR_DE…
안녕하세요! 앱 개발팀의 레이몬드입니다. 2024년에 진행했던 모듈화 여정을 1년 동안의 iOS 모듈화 진행기로 공유했었는데요, 이번에는 그 여정의 다음 단계인 Component 모듈에 대해 이야기해보려 합니다. 지난 글에서는 모놀리식 구조에서 출발해 Core 레이어를 분리하고, 의존성…
안녕하세요, 카카오스타일 지그재그 서비스 FE팀의 제이슨입니다. 올해 저희는 지그재그 앱 내에 포치의 선물가게라는 게임 서비스를 오픈했습니다. 이 글에서는 포치의 선물가게 게임을 웹 환경에서 구현하면서 겪었던 기술적 선택들과 그 과정에서 했던 고민을 공유해보려고 합니다. 포치의 선물가게…
안녕하세요. 지그재그 서비스팀 로빈입니다.🙂 오늘은 저희 팀에서 관리하고 있는 상품상세페이지(Product Detail Page. 이하 PDP) 서비스의 프로젝트 아키텍처에 대해 간단히 소개해보려고 합니다. PDP 서비스는 2024년부터 “Domain-Driven 헥사고날 아키텍처"의…
안녕하세요! 앱개발팀의 레이몬드입니다. 2024년 한 해동안 모듈화를 경험하면서 느낀점들과 후회하는 것들을 글로 써보고자 합니다. 2023년 초부터 논의해 오던 모듈화를 2024년에 본격적으로 진행했고 지금도 모듈화 작업을 이어 나가고 있습니다. 1년동안 진행한 작업들을 되돌아 보니 생…
안녕하세요, 카카오스타일 지그재그 서비스 FE팀의 제이슨입니다. 2023년 초, 저희 팀은 비즈니스와 더불어 기술적인 개선이 필요하다는 것을 느꼈습니다. 그중에서도 특히 여러 지면에서 독립적으로 관리되고 있던 상품 카드 컴포넌트의 일원화 작업이 중요하게 여겨졌고. 이 문제를 해결하기 위…
지그재그는 상품 판매를 촉진하기 위해 이벤트나 기획전을 주요 마케팅 수단으로 활용합니다. 기획전은 한정된 기간 동안 고객에게 특정 상품 정보와 추가적인 할인 혜택을 명확하게 제시하여 판매를 유도하는 역할을 합니다. 따라서 다양한 기획전을 지속적으로 발행해 고객의 관심을 유도하고, 브랜드…
테스트를 거치지 않은 소프트웨어는 없습니다. 하지만 많은 기능을 가져 복잡해진 현대의 소프트웨어를 온전히 테스트하는 것은 굉장히 어려운 일입니다. 이러한 테스트를 자동화하지 않은 채 소프트웨어를 지속적으로 배포하는 것은 불가능에 가깝다고 할 수 있습니다. 이번 글에서는 카카오스타일에서…
카카오스타일에서는 서버 드리븐 UI(Server Driven UI, 이하 SDUI)를 통해 UI의 유연성을 가져가고 있습니다. 서버가 클라이언트 UI를 동적으로 제어하므로써 빌드 및 배포 없이도 UI 업데이트를 할 수 있고, A/B 테스트도 효율적으로 수행할 수 있었습니다. 다만 이렇게…
근래의 많은 기업과 마찬가지로 카카오스타일도 불필요한 비용 낭비가 발생하지 않도록 많은 노력을 기울이고 있습니다. 물론 이전이라고 사용하지 않는 리소스를 방치하며 비용을 낭비한 것은 아니고, 좀 더 세밀한 부분까지 주의를 기울이기 시작했다고 생각해주시면 됩니다. 이번 글은 그 중 하나를…
안녕하세요, 카카오스타일 전시 UX팀의 샌즈입니다. 모두들 알고 계시듯 null(널)은 값이 없음을 나타냅니다. 그리고 null 값인 객체에 접근하려고 하면 그 유명한 NullPointerException(NPE)이 발생합니다. 그런데 null 값을 가지지 않는 다고 설정한 변수에서 N…
이전 글에서는 테스트 전략과, 테스트를 작성하는 방법들에 대해서 알아봤습니다. 하지만, 테스트를 실행하는 환경에 대해서는 스토리북을 사용한다고 가정했을 뿐, 구체적인 이야기를 진행하지는 않았습니다. 이번 글에서는, 테스트 프레임워크를 활용해서 테스트를 자동으로 실행할 수 있는 환경을 구…
이전 글에서는 제품의 요구사항을 분석하며, 테스트 케이스를 산출하는 방법에 대해 알아봤습니다. 이 글에서는 구체적으로 어떻게 테스트 코드를 작성할 수 있는지에 대해 알아봅니다. 첫 번째 글에서 언급한 바와 같이, 프론트엔드의 테스트는 대부분 통합 테스트로 간주될 수 있습니다. 프론트엔드…
저번 글에서는 프론트엔드의 테스트 자동화에 대해서 소개하고, 테스트 전략에 대해서 간단하게 다뤄봤습니다. 테스트 자동화가 아무리 중요하다고 해도, 테스트 작성을 시작하는 것은 쉽지 않습니다. 설정해야 하는 것들이 많고, 효과적인 테스트 작성 방법을 찾는 것도 어렵습니다. 이 문서에서는…
프론트엔드는 입력/출력이 명확하지 않기 때문에 테스트를 작성하면서 고민해봐야 할 내용이 많습니다. 프론트엔드 관점에 맞춰 테스트 자동화, 테스트의 정의와 방향성에 대해서 다뤄봤습니다. 프로젝트가 커질수록 서로 영향을 주는 구성요소들이 증가합니다. 이로 인해 하나의 요소를 수정하면, 전혀…
카카오스타일의 파트너센터 서비스에서는 UI 테스트와 문서화를 위해서 Storybook과 MSW를 사용하고 있습니다. Storybook의 각 스토리마다 MSW GraphQL mock을 개별로 정의해서 사용하고 있었는데, 이로 인해 코드가 중복되고 mock 누락으로 인한 오류가 자주 발생했…
GraphQL.js 리졸버의 마지막 인자는 info입니다. info는 현재 처리 중인 질의에 대한 정보가 들어가 있습니다. 보통은 리졸버 구현에 info가 필요하지 않지만 최적화나 복잡한 연결을 위해서는 info의 내용이 필요합니다. variableValues 속성에는 실행시 준 변수…
GraphQL.js 리졸버의 세번째 인자는 context입니다. 이 인자는 온전히 사용자가 설정하는 것으로 매 요청마다 새로 생성되며 같은 요청을 처리하는 리졸버가 상태를 공유하기 위해 사용합니다. 다음과 같이 적당한 값을 넣어서 한번 실행해보면 동작 방식을 금방 이해할 수 있습니다.…
GraphQL.js 리졸버의 두번째 인자는 args입니다. 해당 필드에 인자가 주어지면 그 값이 들어옵니다. GraphQL Java에서는 DataFetchingEnvironment.getArguments 로 얻을 수 있습니다. 프로그래밍에서 함수 호출에 인자가 있는 것은 당연하기 때문에…
GraphQL.js의 리졸버는 네개의 인자를 가지고 있습니다. 그 중 첫번째 인자는 source 입니다. GraphQL Java에서는 DataFetchingEnvironment.getSource로 얻을 수 있습니다. 앞서 설명했듯이 리졸버는 상위 필드에서 하위 필드 순서로 호출됩니다.…
GraphQL 스키마를 정의했고, 클라이언트에서 온 요청을 서버가 처리하기 위해 필요한 기술을 알아봤습니다. 이제 클라이언트에서 온 요청에 따라 적절한 데이터를 반환하는 과정이 남았습니다. 이는 리졸버(resolver)라는 것이 담당합니다. Java쪽에서는 데이터 페처(data fetc…
이전 글에서 GraphQL 스키마를 정의했습니다. 이제 이 스키마에 질의를 하고 그 결과를 받을 수 있습니다. graphql 메소드를 써서 질의를 할 수 있습니다. import { graphql, GraphQLList, GraphQLNonNull, GraphQLObjectType, Gr…
안녕하세요! 카카오스타일 SRE팀 네사입니다. 오늘은 카카오스타일 SRE팀에서 올해 EKS 클러스터 이전을 하며 새롭게 도입 했던 AWS Karpenter 에 대해 공유를 해보려 합니다. EKS 클러스터를 운영하는 엔지니어라면 누구나 확장성에 대한 고민을 한 번쯤 하게 됩니다. agil…
안녕하세요! 👋 카카오스타일 프론트엔드 챕터 소속 Jason(제이슨/황주성)입니다. 여러분은 혹시 서비스를 개발하면서 브라우저의 윈도우, 탭 혹은 웹뷰 액티비티 간 데이터를 동기화 해줘야 했던 경험이 있으신가요? 페이스북이나 인스타그램과 같이 사용자가 상세 페이지에서 게시물 좋아요를 누…
GraphQL이란 것은 대부분 들어보셨을 것으로 생각합니다. 그리고 페이스북이 만들었다는 것 정도는 아실 것 같습니다. 근데 여기서 말하는 GraphQL이란 뭘까요? GraphQL 자체는 데이터 query를 어떻게 할지만 정해놓았습니다. 즉 type User { id: ID! name:…
반복해서 실수가 발생해서 수많은 사람들의 시간을 낭비하는데, 사실 시스템 개선에 조금만 시간을 썼으면 발생하지 않았을, 그런 문제들이 있습니다. 이런 상황을 알면서도 바쁘다는 핑계로 넘어가곤 하는데, 이번에 1년 이상 머리 한 구석에만 뒀던 이슈를 해결해 공유해볼까 합니다. 카카오스타일…
저희는 주기적으로 Node.js 모듈을 최신 버전으로 업데이트하고 있습니다. Node.js를 10년째 사용 중인데, CoffeeScript → TypeScript, 콜백 → Async.js → Promise(& async, await) 전환 하면서 몇 번 혼란의 시기가 있었습니다. 하지…
이전 글에서는 ECS / EKS에서 서비스 하는 것에 대한 개념을 풀어 써봤습니다. 이번 글에서는 잘 만들어진 모듈을 이용해 빠르게 구성해보겠습니다. 모듈을 이용하면 편하긴 하지만 내부 개념을 정확히 이해하지 못한 채 사용하면 문제가 발생했을 때 해결이 어려운 것 같습니다. 결국 기본이…
ECS 아티클에 이어 이번 글에서는 같은 서비스를 EKS로 구축해보도록 하겠습니다. 간단하게 구축하는 것은 eksctl을 쓰면 되지만, 내부 이해를 위해 여기서는 기본부터 구현하도록 하겠습니다. VPC는 이전과 마찬가지로 두 개의 AZ에 퍼블릭 서브넷과 프리이빗 서브넷이 필요합니다. 다…
카카오스타일에서는 한동한 ECS를 사용해서 어플리케이션을 서비스했습니다. 현재는 EKS로 전환하고 있지만, ECS가 상대적으로 단순하기 때문에 서비스 구축 개념을 익히는데 좋은 것 같습니다. (간단한 서비스는 굳이 쿠버네티스를 쓸 필요가 없다고 생각합니다) 그런 의미에서 이번 글에서는…
Photo by Mariah Krafft on Unslpash 안녕하세요! 👋 카카오스타일 프론트엔드 챕터 소속 Jason(제이슨/황주성)입니다. 회사나 팀에서 개발하다 보면 한 번쯤은 거의 필연적으로 내부에서 사용하기 위한 패키지 저장소에 대해 고민해보게 됩니다. 오늘은 그 고민을 통…
이번 글에서는 카카오스타일에서 Jotai를 어떤 식으로 사용하고 있는지 여러가지 패턴에 대해 설명하려고 합니다. Jotai의 기본 사용법은 간단합니다. useState로 정의하던 상태가 있으면, atom 메소드로 정의하고 useAtom을 써서 사용하면 됩니다. import { atom,…
카카오스타일은 React에서 상태 관리를 위해 최근에 Jotai를 도입했습니다. Jotai에 대해 소개하기에 앞서 Jotai에 다다르기까지의 과정에 대해 설명해보려고 합니다. 할일 관리 화면을 상상해봅시다. 초기 웹에서 보편적이였던 jQuery를 사용한다면, 할 일 추가를 위해 다음과…
웹과 달리 네이티브 모바일 앱은 빌드, 배포 후에는 수정이 불가능합니다. 만약 잘못된 위치에 버튼을 배치한 채로 스토어에 앱을 배포했다면, 그리고 사용자가 잘못된 버전의 앱을 설치했다면 버튼의 위치를 수정할 방법이 없습니다. 유일한 방법은 사용자가 스스로 스토어에 들어가 수정된 버전의…
Java로 코드를 작성해보신 분이라면 throws에 의해 컴파일 에러가 발생했을 때 뭔지는 잘 모르겠고 IDE가 제시한 대로 catch로 감싸고 넘어간 경험이 누구에게나 있을 것이라 생각합니다. 그만큼 예외 상황은 잘 이해하고 적절히 처리하기는 쉽지 않은 것 같습니다. 오늘은 카카오스타…
프로젝트가 시작된지 얼마 되지 않은 경우에 소스는 비교적 일관성을 가지고 있습니다. 하지만 시간이 지남에 따라 여러 사람이 참여하고, 비슷한 새로운 프로젝트가 만들어지면서 점점 일관성이 떨어지게 됩니다. (문서나 리뷰 과정이 있으면 비교적 낫지만, 완전히 방지하기는 어려운 것 같습니다)…
규모가 커지면 커질 수록 자동화된 워크플로우는 필수라고 생각합니다. 하지만 부끄럽게도 크로키닷컴은 잘 구축된 편은 아닙니다. 유닛 테스트는 초기부터 있었지만 그걸 PR, 머지마다 자동으로 수행하지는 못했습니다. 그러다가 2017년 중반 겨우 Jenkins를 세팅해서 자동 테스트만은 수행…
응용프로그램을 작성하다 보면 여러 가지 환경 설정(configuration)이 필요합니다. 이번 글에서는 TypeScript에서 환경 설정을 관리하는 저희의 방법을 설명합니다. 프로젝트 초기에는 환경 설정을 코드 중간에 넣어서 개발하는 경우가 많을 것으로 생각합니다. 그러다가 규모가 커…
서비스를 운영하다 보면 주기적으로 실행이 필요한 작업이 생깁니다. 이런 작업을 실행하는 방법은 여러 가지가 있을 수 있습니다. 다음은 크로키에서 현재 선택해서 전환 중인 AWS Batch에 관해 설명합니다. 지그재그 서비스 초기에는 서버가 EC2 인스턴스 위에서 동작하고 있었습니다. 이…
현재 크로키는 API를 GraphQL로 만들고 있습니다. 아직 많은 부분에 대해서 연구 중이어서 현재 상황만 간단하게 정리해 보겠습니다. Thrift를 1년 정도 쓴 시점부터 여러 가지 불편함을 느끼고 대안을 찾다가 GraphQL을 선택했습니다. GraphQL 생태계가 Node.js를…
안녕하세요 지그재그에서 프론트엔드 개발을 하고 있는 태재영입니다. 프론트엔드 개발자에게 중앙 정렬을 어떻게 하냐고 물어보면 inline 요소는 text-align 속성을 center로 지정하고, block 요소는 margin 속성을 auto로 지정한다고 대답할 겁니다. 그런데 좌우가 아…
2016년 중반 마이크로서비스로의 전환을 결정했습니다. 마이크로서비스는 이론상 다른 서비스에 영향을 주지 않고 내부 기술을 바꿀 수 있습니다. 하지만 마이크로서비스 간의 통신 방법은 한번 결정하면 쉽게 바뀌기 어려울 것 같아서 가장 많이 고민했습니다. 그리고 Thrift를 선택했습니다.…
크로키닷컴을 시작하고 비교적 초기부터 ChatOps를 해보고 싶었습니다. GitHub의 글을 보고 도입하고 싶다는 생각이 들었던 거로 기억합니다. 당연하게 Hubot을 이용해 채팅봇을 설정했습니다. 초기에는 HipChat에 Hubot을 붙였고, 2014년 중반 Slack으로 전환했습니다…
안녕하세요! 저는 개발팀의 오형준입니다. 앞선 글에서 데이터팀의 지형님께서 ‘분석용 이벤트 로그 점검/정리하기’라는 Task가 어떤 Task이며, 왜 중요한지에 대해 다루었다면, 이번 글에서는 이번 Task의 프로세스, 앱개발팀과 데이터팀 간의 협업 방식, 각 팀의 업무 방식 등에 대해…
28일 오전, 한참 작업을 하다가 11시가 조금 넘은 시간에 문득 핸드폰을 들여다봤습니다. 평상시 메일은 몰아서 처리하는 편인데(시급한 일이 메일로 오는 경우는 드물어서) 이날은 왠지 메일에 눈이 갔습니다. AWS에서 보낸 메일이 보였는데, 자주 오던 광고성 메일은 아니었고 Mainte…
지그재그는 누적 다운로드 수 1,100만, MAU 200만을 넘어가고 있는 여성 쇼핑몰 모음 앱 서비스입니다. 그렇기 때문에 매일같이 지그재그에 쌓여가는 이용자들의 데이터 로그들도 어마어마하죠. 이와 같은 로그들은 이용자들이 각자 자신에게 맞는 쇼핑몰/상품을 더 쉽게, 편하게 찾을 수…
크로키가 클라이언트-서버 아키텍처를 가진 첫 번째 서비스 개발을 시작한 것은 2012년이었습니다. 클라이언트에서 서버와 통신할 방법이 필요했는데 당시의 대세는 REST API였습니다. 저도 거기에 공감했기 때문에 REST API를 만들어 클라이언트를 구현했습니다. 그 후로 모든 서비스는…
오늘날의 소프트웨어 개발에 있어서 지속적 통합(continuous integration)은 필수라고 할 수 있습니다. 저도 당연히 동의하면서 오래전부터 도입하려고 했지만, 급한 일에 밀려 실제로 도입한 것은 지그재그 서비스를 오픈하고 나서도 2년이나 지난 작년 여름무렵입니다. 여러가지…
(2022년 4월 갱신) 카카오스타일에서는 최고의 개발팀을 만들기 위해 항상 노력하고 있습니다. 이 글에서는 카카오스타일 개발팀의 문화와 관심사에 대해서 소개하고 있습니다. 카카오스타일에서 운영하고 있는 서비스에 대해서는 하단의 소개를 참고해주세요. 이 글을 읽고 카카오스타일의 개발팀에…
지그재그 서비스는 모놀리식 아키텍처(Monolithic Architecture)에서 마이크로서비스 아키텍처(Microservice Architecture)로 전환중에 있습니다. 이번 글에서는 그 과정을 설명하려고 합니다. 크로키는 2012년 중반에 첫 서비스 개발을 시작했습니다. 웹 서…
최근 클라우드 컴퓨팅환경이 널리 사용되면서 서버 하드웨어 대한 유지보수 및 구성을 신경 쓰지 않고, 다양한 서비스들을 위한 서버를 개발할 수 있게 되었습니다. 하지만 이런 환경을 사용함에도 auto-scaling이나 서버 로그 수집, 서비스 배포 및 관리 등 소프트웨어 스택에 관한 부분…
클라이언트 JavaScript 개발 환경은 빠르게 변화하고 있습니다. 다양한 관련 기술 중 빌드 툴 쪽에서 최근 가장 주목 받는 것은 webpack이라고 할 수 있습니다. webpack 전체는 굉장히 방대하기 때문에 한번에 이해하기가 쉽지 않습니다. 인터넷에 이미 잘 구성된 설정파일이…
이번 글에서는 크로키가 사용하는 스택 중 클라이언트 JavaScript 프레임워크(client-side JavaScript framework)에 대해서 소개해볼까 합니다. TD;DR) 크로키에서는 Backbone, Angular를 거쳐 현재는 Mithril이라는 프레임워크를 사용하고 있…
현재 크로키에서는 서버용 웹 프레임워크로 Node.js 위에서 Express를 사용하고 있습니다. 이번 글에서는 어떤 이유로 Node.js를 사용하게 되었는지 설명하려고 합니다. 여러분들이 웹 프레임워크를 선택하시는 데 참고가 되었으면 합니다. 크로크닷컴을 설립한 것은 2012년 2월입…
크로키에서는 로그를 JSON 문자열로 만들어 일자별(혹은 시간별)로 묶은 후 gzip으로 압축해서 저장하고 있습니다. 그런데 이미 만들어진 로그를 수정해야 하는 일이 생겼습니다. 예를 들면 {"date":"Fri Jan 15 2016 00:00:01 GMT+0000 (UTC)","pat…
현재 크로키닷컴은 프로젝트 관리를 GitHub로만 하고 있습니다. 이슈도 GitHub 이슈로 관리하고, 문서도 GitHub 위키를 사용하고 있습니다. GitHub는 슬랙과의 연동이 잘 되어 있어서 GitHub에서의 활동을 슬랙을 통해 파악하고 대응하고 있습니다. 하지만 아쉽게도 GitH…
지그재그 앱을 사용하는 사용자를 분석할 때 사용하기 위해서 최근 업데이트에 나이를 입력받는 화면이 추가되었습니다. 입력은 나이를 받지만 나이는 매년 달라지기 때문에 고정된 값인 태어난 년도로 변환하여 저장하고 있습니다. 그런데 대부분은 정상적인 년도가 들어오는데 일부 사용자의 태어난 년…