❓
물음표살인마 블로그
  • README
  • ALGORITHM
    • Sieve of Eratosthenes
    • Round Up
    • Binary Search
    • Union Find
    • Sorting Array
    • Lcm, Gcd
  • TechTalk Review
    • Template
  • Books
    • CS Note for Interview
      • Ch1. Design Pattern & Programming paradigm
        • 1.1.1 Singleton Pattern
        • 1.1.2 Factory Pattern
        • 1.1.4 Observer Pattern
        • 1.1.5 Proxty Pattern & Proxy Server
        • 1.1.8 Model-View-Controller Pattern
        • 1.2.1 Declarative and Functional Programming
        • 1.2.2 Object Oriented Programming
      • Ch2. Network
        • 2.2.1 TCP/IP Four-Layer Model
        • 2.2.1-1 TCP 3, 4 way handshake
        • 2.3 Network Devices L4, L7
        • 2.4.1 ARP, RARP
        • 2.4.2 Hop By Hop Communication
        • 2.4.3 IP Addressing Scheme
      • Ch3. Operating System
        • 3.1.1 Roles and Structure of Operating Systems
        • 3.2.1 Memory Hierarchy
        • 3.2.2 Memory Management
        • 3.3.1 Processes and Compilation Process
        • 3.3.3 Memory Structure of a Process
        • 3.3.4 Process Control Block (PCB)
        • 3.3.5 Multiprocessing
        • 3.3.6 Threads and Multithreading
        • 3.3.7 Shared Resources and Critical Sections
        • 3.3.8 Deadlock
        • 3.4 CPU Scheduling Algorithm
      • Ch4. Database
        • 4.1 Database Basic
        • 4.2 Normalization
        • 4.3 Transaction and Integrity
        • 4.4 Types of Databases
        • 4.5 Indexes
        • 4.6 Types of Joins
        • 4.7 Principles of Joins
      • Ch5. Data Structure
    • Learning the Basics of Large-Scale System Design through Virtual Interview Cases
      • 1. Scalability based on user counts(1/2)
      • 1. Scalability based on user counts(2/2)
      • 2.Back-of-the-envelope estimation
      • 3. Strategies for System Design Interviews
      • 4. Rate Limiter
      • 5. Consistent Hashing
      • 6. Key-Value System Design
      • 7. Designing a Unique ID Generator for Distributed Systems
      • 8. Designing a URL Shortener
      • 9. Designing a Web Crawler
      • 10. Notification System Design
      • 11. Designing a News Feed System
      • 12. Chat System Design
      • 13. AutoComplete
      • 14. Design YouTube
      • 15. Design Google Drive
      • Loadbalancer Algorithms
      • Cache tier
      • CDN, Content Delivery Network
      • Stateless Web tier
    • Computer System A programmer's perspective
    • Effective Java
      • Item 1. Consider Static Factory Methods Instead of Constructors
      • Item 2. Consider a Builder When Faced with Many Constructor Parameters
      • Item 3. Ensure Singleton with Private Constructor or Enum Type
      • Item 4. Enforce Noninstantiability with a Private Constructor
      • Item 5. Prefer Dependency Injection to Hardwiring Resources
      • Item 6. Avoid Creating Unnecessary Objects
      • Item 7. Eliminate Obsolete Object References
      • Item 8. Avoid Finalizers and Cleaners
      • Item 9.Prefer try-with-resources to try-finally
      • Item10. Adhering to General Rules When Overriding equals
        • Handling Transitivity Issues
        • Ensuring Consistency
      • Item11. Override hashCode When You Override equals
      • Item12. Always Override toString
        • Always Override toString
      • Item13. Override Clone Judiciously
      • Item14. Consider Implementing Comparable
      • Item15. Minimize the Accessibility of Classes and Members
      • Item16. Accessor Methods Over Public Fields
      • Item17. Minimize Mutability
      • Item18. Composition over inherentance
      • Item19. Design and Document for Inheritance, or Else Prohibit It
      • Item20. Prefer Interfaces to Abstract Classes
      • Item21. Design Interfaces with Implementations in Mind
      • Item22. Use Interfaces Only to define Types
      • Item23. Prefer Class Hierarchies to Tagged Classes
      • Item24. Favor Static Member Classes Over Non-Static
      • Item28. Use Lists Instead of Arrays
      • Item29. Prefer Generic Types
      • Item30. Favor Generic Methods
    • Head First Design Patterns
      • Ch1. Strategy Pattern
      • Ch2. Observer Pattern
        • Ver1. Ch2. Observer Pattern
      • Ch3. Decorator Pattern
        • Ch3. Decorator Pattern
      • Ch4. Factory Pattern
      • Ch5. Singleton Pattern
      • Ch6. Command Pattern
      • Ch7. Adapter and Facade Pattern
      • Ch8. Template Method Pattern
    • Digging Deep into JVM
      • Chapter 2. Java Memory Area & Memory Overflow
      • Chapter 3. Garbage Collector & Memory Allocation Strategy (1/2)
      • Chapter 3. Garbage Collector & Memory Allocation Strategy (2/2)
      • Chapter 5. Optimization Practice
      • Chapter 6. Class file structure
      • Chapter 8. Bytecode Executor Engine (1/2)
  • Interview Practices
    • Restful API Practices
      • Url Shortener API
      • Event Ticket Reservation API
      • Course Management API
      • Search posts by tags API
      • Online Code platform API
      • Simple Task Management API
      • Event Participation API
      • Review System API
      • Car management API
      • Online Library
    • Tech Review
      • if(kakao)
        • Kakao Account Cache Migration / if(kakao)2022
        • Improving the Anomaly Detection System for KakaoTalk Messaging Metrics / if(kakao) 2022
        • Standardizing API Case Handling Without Redeployment / if(kakaoAI)2024
        • JVM warm up / if(kakao)2022
    • Naver Computer Science
      • Process & Thread
      • TCP & UDP
      • Spring & Servlet
      • Filter & Interceptor & AOP
      • Equals() & ==
      • Dependency Injection
      • Object Oriented Programming
  • F-Lab
    • Week1
      • Client & Server
      • HTTP
      • TCP/UDP
      • REST API
      • Questions
        • Object Oriented Programming
        • HTTP
        • Process & Thread
        • Data Structure
    • Week2
      • OSI 7 layer
      • Web vs WAS
    • Week3
      • RDB vs NoSQL
      • RDB Index
      • Cache
      • Redis
      • Messaging Queue
    • Week4
      • Project - Ecommerce
    • Week5
      • ERD - 1
    • Week6
      • Ecommerce - 2
      • Role
      • pw hashing && Salt
      • CreatedAt, ModifiedAt
      • JWT
      • Copy of ERD - 1
    • Week7
      • Vault (HashiCorp Vault)
    • Week 8
      • Api Endpoints
    • Week10
      • Product Create Workflow
  • TOY Project
    • CodeMentor
      • Implementation of Kafka
      • Project Improvement (Architectural Enhancements)
      • Communication between servers in msa
  • JAVA
    • MESI protocol in CAS
    • CAS (Compare and Set)
    • BlockingQueue
    • Producer & Consumer
    • Synchronized && ReentrantLock
    • Memory Visibility
    • Checked vs Unchecked Exception
    • Thread
    • Batch delete instead of Cascade
    • Java Questions
      • Week 1(1/2) - Basic Java
      • Week 1(2/2) - OOP
      • Week 2(1/2) - String, Exception, Generic
      • Week2(2/2) Lambda, Stream, Annotation, Reflection
      • Week3(1/2) Collections
      • Week3(2/2) Threads
      • Week4 Java Concurrency Programming
      • Week5 JVM & GC
    • Java 101
      • JVM Structure
      • Java Compiles and Execution Method
      • Override, Overload
      • Interface vs Abstract Class
      • Primitive vs Object Type
      • Identity and equality
      • String, StringBuilder, StringBuffer
      • Checked Exceptions and Unchecked Exceptions
      • Java 8 methods
      • Try-with-reources
      • Strong Coupling and Loose Coupling
      • Serialization and Deserialization
      • Concurrency Programming in Java
      • Mutable vs Immutable
      • JDK vs JRE
  • SPRING
    • DIP. Dependency Inversion Principal
    • Ioc container, di practice
    • @Transactional
    • Proxy Pattern
    • Strategy Pattern
    • Template Method Pattern
    • using profile name as variable
    • Spring Questions
      • Spring Framework
      • Spring MVC & Web Request
      • AOP (Aspect-Oriented Programming)
      • Spring Boot
      • ORM & Data Access
      • Security
      • ETC
  • DATABASE
    • Enhancing Query Performance & Stability - User list
    • Ensuring Data Consistency, Atomicity and UX Optimization (feat.Firebase)
    • Redis: Remote Dictionary Server
    • Database Questions
      • Week1 DBMS, RDBMS basics
      • Week2 SQL
      • Week3 Index
      • Week4 Anomaly, Functional Dependency, Normalization
      • Week5 DB Transaction, Recovery
    • Normalization
      • 1st Normal Form
      • 2nd Normal Form
      • 3rd Normal Form
  • NETWORK
    • HTTP & TCP head of line blocking
    • HTTP 0.9-3.0
    • Blocking, NonBlocking and Sync, Async
    • Network Questions
      • Week1 Computer Network Basic
      • Week2(1/3) Application Layer Protocol - HTTP
      • Week2(2/3) Application Layer Protocol - HTTPS
      • Week2(3/3) Application Layer Protocol - DNS
      • Week3 Application Layer
      • Week4 Transport Layer - UDP, TCP
      • Week5 Network Layer - IP Protocol
    • Network 101
      • https://www.google.com
      • TCP vs UDP
      • Http vs Https
      • TLS Handshake 1.2
      • HTTP Method
      • CORS & SOP
      • Web Server Software
  • OS
    • Operating System Questions
      • Week1 OS & How Computer Systems Work
      • Week2(1/2) Process
      • Week2(2/2) Thread
      • Week3 CPU Scheduling
      • Week4 Process Synchronize
      • Week5 Virtual Memory
    • Operating System 101
      • Operating system
        • The role of the operating system
        • The composition of the operating system.
      • Process
        • In Linux, are all processes except the initial process child processes?
        • Zombie process, orphan process
        • (Linux) Daemon process
        • Process address space
        • Where are uninitialized variables stored?
        • Determination of the size of the Stack and Heap
        • Access speed of Stack vs Heap
        • Reason for memory space partitioning
        • Process of compiling a process
        • sudo kill -9 $CURRENT_PID
      • Thread
        • Composition of a thread's address space
      • Process vs Thread
        • Creation of processes and threads in Linux
      • Multiprocessing
        • Web Browser
        • Implementation of multiprocessing
        • Application areas of multiprocessing
      • Multithreading
        • Application areas of multithreading
      • Interrupt
        • HW / SW Interrupt
        • Method of handling interrupts
        • Occurrence of two or more interrupts simultaneously
      • Polling
      • Dual Mode
        • Reason for distinguishing between user mode and kernel mode
      • System call
        • Differentiation between system calls
        • Types of system calls
        • Execution process of a system call
      • Process Control Block (PCB)
        • PCB의 구조
        • 쓰레드는 PCB를 갖고 있을까?
        • 프로세스 메모리 구조
      • Context switching
        • Timing of context switching
        • Registers saved during context switching
        • Context switching in processes
        • Context switching in threads
        • Difference between context switching in processes and threads
        • Information of the current process during context switching
      • Interprocess Communication (IPC)
        • Cases where IPC is used
        • Process address space in IPC Shared Memory technique
        • Types of IPC
  • COMPUTER SCIENCE
    • Computer Architecture 101
      • 3 components of a computer
      • RAM vs ROM
      • CPU vs GPU
      • SIMD
      • Two's complement
      • Harvard Architecture vs. von Neumann Architecture
      • The structure of a CPU.
      • Instruction cycle (CPU operation method)
      • Instruction pipelining
      • Bus
      • Memory area
      • Memory hierarchy structure
        • Reason for using memory hierarchy structure
      • Cache memory
      • L1, L2, L3 Cache
      • Locality of reference (cache)
      • Fixed-point vs Floating-point
        • epresentation of infinity and NaN (Not a Number) in floating-point
      • RISC vs CISC
      • Hamming code
      • Compiler
      • Linking
      • Compiler vs Interpreter
      • Mutex vs Semaphore
      • 32bit CPU and 64bit CPU
      • Local vs Static Variable
      • Page
  • Programming Paradigm
    • Declarative vs Imperative
  • JPA, QueryDsl
    • why fetchResults() is deprecated
  • PYTHON
    • Icecream
  • FASTAPI
    • Template Page
  • LINUX
    • Template Page
  • DATA STRUCTURE
    • Counting Sort
    • Array vs Linked List
  • GIT, Github
    • git clone, invalid path error
  • INFRA
    • Template Page
  • AWS
    • Server Log Archive Pipeline
    • Image Processing using Lambda
  • DOCKER
    • Docker and VM
    • Python Executable Environment
    • Docker commands
  • docker-compose
    • Kafka, Multi Broker
  • KUBERNATES
    • !Encountered Errors
      • my-sql restarts
      • kafka producer: disconnected
    • Kubernetes Components
    • Helm
      • Helm commands
    • Pod network
    • Service network
      • deployment.yaml
      • services.yaml
    • Service type
      • Cluster IP
      • NodePort
    • service-name-headless?
    • kube-proxy
  • GraphQL
    • Template Page
  • WEB
    • Template Page
  • Reviews
    • Graphic Intern Review
    • Kakao Brain Pathfinder Review
    • JSCODE 자바 1기 Review
  • 😁Dev Jokes
    • Image
      • Plot twist
      • Priorities
      • SQL join guide
      • Google is generous
      • Genie dislikes cloud
      • buggy bugs
      • last day of unpaid internship
      • what if clients know how to inspect
      • its just game
      • how i wrote my achievement on resume
      • self explanatory
      • chr(sum(range(ord(min(str(not))))))
Powered by GitBook
On this page
  1. Interview Practices
  2. Tech Review
  3. if(kakao)

Standardizing API Case Handling Without Redeployment / if(kakaoAI)2024

추가 배포 없이 API의 case 통일시키기 / if(kakaoAI)2024

https://www.youtube.com/watch?v=ZE5xgQuvHFQ&list=PLwe9WEhzDhwGXZ0REjCOYosGkrDkkHZKk&index=7&ab_channel=kakaotech

서비스 스펙

프레임 워크 : Spring

Parser : Jackson

Domain : 한달 주기로 결제를 진행하는 구독 서비스

사용 중인 CASE 종류: 카멜, 스네이크, 케밥

변경하려고 했을 때 만난 문제들

  1. API 전달 시 CASE가 다른 경우

    • 최초 요청은 카멜, 전달받는 쪽에서 스네이크를 요구하는 경우

    • 하나의 요청에 두 개의 DTO가 필요하게 됨

  2. DTO 내부에 CASE가 다른 DTO를 포함시켜야 하는 경우

    • DTO 내, 외부의 CASE가 섞여있음

    • 받는 쪽에서는 어느 CASE로 파싱을 해야할 지 모르는 경우가 생김

  3. Jackson에서 Unknown Property설정의 default false설정으로 인해 매핑되지 않는 필드가 있더라도 예외를 던지지 않고 런타임에 도달해야 해당 필드가 null임을 알 수 있음.

  4. MSA 환경에서 무중단 배포를 하기 위해서는:

    1. Callee쪽에서 변경할 CASE의 API를 새로운 버전으로 배포

      1. Caller: v1/api/users

      2. Callee: v1/api/users, v2/api/users (new!)

    2. Caller쪽에서 버전 변경한 API 배포

      1. Caller: v1 → v2/api/users (new!)

      2. Callee: v1/api/users(deprecated), v2/api/users

    3. Callee쪽에서 이전 버전 API 삭제

      1. Caller: v2/api/users

      2. Callee: v2/api/users

    Callee가 많아지면, 대규모 배포하기 위해 서버점검을 걸고 작업을 하는게 문제

처리방안

  1. 모든 서버에 CASE와 상관없이 파싱이 가능하도록 해주는 모듈 추가

  • 대상이 되는 서버에 모듈을 설정

  • Request DTO에는 RequestBodyAdvice 사용

  • Response DTO에는 Custom Deserializer 사용한 모듈 설정

    • 케이스와 상관 없이 받아주는 서버 케이스에 맞춰 요청을 변경하는 전략

  1. 각 서버의 CASE를 하나로 통합하고, 변경 모듈 삭제

Request 처리

  • Filter 사용: 아직 어느 Controller에 매핑됐는지 모르는 상태. Target class에 맞춘 parsing불가.

  • Intercepter 사용: Target class는 알 수 있지만, Request를 DispatcherServlet에서 받은 그대로 돌려주기 때문에 변경 불가.

    • 인터셉터에서는 기존의 Request를 변조할 수 없음

    • 변조하려면 Byte 코드를 조작해야 하는데, 위험성이 존재함

    • 스프링에서 지원하는 인터페이스 또한 없기에 불가능.

  • AOP 사용

    • SpringMVC에서 사용할 수 있는 RequestBodyAdvice를 사용

    • Controller를 찾아, RequestBody에 Value를 매핑하기 직전 적용됨.

    public interface RequestBodyAdvice {
    	boolean supports(..);
    	HttpInputMessage beforeBodyRead(..); <-body를 읽기전에, 작업
    	Object afterBodyRead(..); }
  • RequestBodyAdvice 사용 전략, beforeBodyRead 구현

    1. 스네이크로 먼저 변환하고, Error가 잡히면 Camel로 변경 → 실패

      • Unknwon Property=FALSE 설정 때문에 에러로 잡히는 것이 아니라 null 값이 설정

    2. 어노테이션 활용 → 성공

      • Snake 변환 시 @JsonNamingProerty, @JsonProperty 사용

      • 타겟 클래스에 두 가지의 어노테이션이 존재하는지 확인하고 Snake 변경 여부 판단

  • Edge Cases 처리:

    • Json의 Key만 변경해야하는 경우

      • JsonNode로 Key만 뽑아내서 convert

    • 여러개의 Generic이 중첩되는 경우

      • Generic 사이에 case가 다른 경우 오류라고 가정. 가장 InnerDto를 기준으로 parsing 작업 처리.’

      • "Generic 사이에 case가 다른 경우 오류라고 가정"하는 이유는?

        현실적으로 모든 중첩 Generic의 케이스를 정확히 감지하고 처리하는 건 불가능에 가깝습니다

        • ApiResponse<PageResponse<YourDto>>처럼 중첩 구조에서,

        • ApiResponse는 camelCase, PageResponse는 kebab-case, YourDto는 snake_case라면?

        • 각 레벨마다 서로 다른 변환 전략을 적용해야 하고, JSON 파싱 시 중간 구조(Wrapper)를 지나서 내부 DTO까지 정확하게 매핑하기 위해선 각 타입을 다 추적해야 함.

        • 그래서 그냥 InnerDto를 기준으로 parsing작업을 처리해서, 나머지 필드는 무시.

          • OuterDto: Kebab → CamelToSnake: null값

          • InnerDto: Camel → CamelToSnake: 정상적으로 변환

    • Map과 같이 타입이 두개 이상 가진 제너릭일 경우 제외

      • 클래스의 클래스를 재귀적으로 탐색해야함

        • 타입이 두개 이상인 클래스는 Map 제외하고는 없었음.

        • Map의 Key값을 실제 변수명으로 사용할 때가 있어 Map을 제외함.

Response 처리

  • 서버에서 필요한 응답값을 외부에 요청하고, 받을때 Wrapper class 사용중.

  • Jackson에서 특정 클래스에 Custom한 Deserializer를 적용하는 기능을 사용하기로 결정

    • Override된 deserialize 메서드 사용

    • RequestBodyAdvice에 적용한 로직을 그대로 적용

      • 기준 Generic 추출

      • Map타입 제외

      • 어노테이션을 통한 Case 판단

  • Trouble Shooting

    • Jackson 내부에서 Deserializer는 map에 캐싱되어 재사용됨 (동시성 문제)

    @Override
    public JsonDeserializer<?> createContextual(
    		DeserializationContext ctxt,
    		BeanProperty property
    ){
    		var type = property != null?
    		property.getType() : ctxt.getContextualType();
    		
    		//return this; 일 경우 이전에 캐싱된 type으로 파싱되기에 error발생
    		return new CustomDeserializer(type); //따라서 원하는 타입으로 인스턴스를 따로 생성함
    }

결론

외부에서 어떤 케이스든, 두 가지 모듈이 적용된 상태에서는 원하는 형태의 케이스로 변환할 수 있음

  • Caller와 Callee를 반복적으로 배포할 필요가 없어짐

  • 배포 순서 문제도 없어짐

  • 의도치 않은 케이스가 있는지는 로그를 통해 일정기간 모니터링

결과:

  • 총 900개 가량의 DTO를 서비스 중단 없이 일원화

  • CASE 또한 프로토콜의 일부로, 복잡성을 높이는 원인이 될 수 있음

  • 팀 내 코딩 컨벤션이 있었기 때문에 가능했던 작업

    • 정규표현식을 이용해 case를 변경했기 때문에 숫자나 영어 대문자가 있었으면 의도하지 않은 결과가 나올 수 있었음

    • Naming, Wrapper class rule이 있어서 ApiResponse Dto에 커스텀 Deserializer를 일괄적으로 처리할 수 있었음.

  • 팀 내 코딩 컨벤션은 쉬운 변경을 위한 기초가 됨

제한사항:

  • 변환 과정에서 리플렉션을 사용하기 떄문에 속도에 민감하면 적용 고려 필요

  • RequestBodyAdvice는 MVC에만 적용이 가능하기 때문에 Webflux에는 적용 불가

PreviousImproving the Anomaly Detection System for KakaoTalk Messaging Metrics / if(kakao) 2022NextJVM warm up / if(kakao)2022

Last updated 12 days ago

Image
Image