콘텐츠로 이동

2023 09 14

2023-09-14

Play Action을 알아보자...

  • Action이란?
    • 플레이 프레임워크에서 들어오는 HTTP 요청과 나가는 HTTP 응답을 다루는데 사용
    • 라우터 ↔ Action ↔ Controller
  • 다음과 같은 역할을 할 수 있어요

    • [기본 구조]
      • 요청 받고 응답 하는 구조
        def myAction: Action[AnyContent] = Action { request =>
            Ok("Hello World!")
        }
        
    • [요청 다루기]
      • 라우트에 작성한 알맞은 HTTP 요청이 들어오면, 그에 상응하는 Action이 호출됨
      • 요청의 파라미터에는 여러가지 요청을 다루는 정보가 들어있음 (헤더, 파라미터, 바디)
    • [응답 뱉기]
      • Action 함수에는 어플리케이션 로직을 다룰 수 있도록 지원함
        • DB 쿼리하고, 요청 보낼거 보내고, validation 할거 하고...
      • Result 객체를 Http 응답으로 뱉는다
    • [Action 합성]
      • Action을 합성해 재사용할 수 있도록 플레이가 지원
      • andThen 과 compose 를 통해서 합성할 수 있음
        • 이러면 여러개의 action을 수행하도록 지원함
          • 인증/인가, 로깅, 요청 파싱 등
    • [비동기적 Action]
      • 플레이는 비동기적 액션을 지원하여 오래 걸리는 연산 (DB 요청, 네트워크 갔다올 일) 등을 효율적으로 처리함
      • Action.async 를 통해 비동기처리 해주고, 이는 Future[Result]를 반환
    • [Body Parsing]
      • Action에서 바디 파싱도 할 수 있어 (JSON, XML, 폼데이터)
    • [요청 필터]
      • 컨트롤러 로직 들어가기전 필터/미들웨어(ACL) 도입하여 처리할 수 있어
      • Logging, Security Check, Request Modification

Play에서 세션을 저장하기

  • 세션을 HTTP 요청에서 가져오기
    • request.session.get(TOKEN_KEY).flatMap(e => Token.decode(e))
      • request는 RequestHeader 타입
  • 토큰의 유효성 검사
    • t.isValid(토큰을 만든 요소들)
  • HTTP 응답에 세션 껴주기
    • (block: ReceiptUser => Future[Result])
      block(user).map(result => session match {
        case Some(s) => result.addingToSession(s.tuple)(request)
        case _ => result
      })
      
  • 복습 : 어떻게 세션은 같은 키 값으로 사용자마다 알맞는 세션을 가져올 수 있는가?
    • Session cookie를 파싱해 Session 데이터를 만듦
      • 요청의 세션 쿠키는 requset.RequestAttrKey.Session에 저장
    • Session 자체가 Map
    • .get(key) 하면 value 뱉음
    • 즉, 사용자별로 알맞은 Session을 만들수있고 (이것도 map이것지?), 해당 Session 역시 ("A" -> Session) 이니 가능한 구조