0Pricing
Scala for Backend Engineering & Functional Programming · 강의

JSON 엔드포인트

http4s와 Circe를 결합해 보세요.

JSON 엔드포인트은(는) CoddyKit의 무료 Scala for Backend Engineering & Functional Programming 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Scala for Backend Engineering & Functional Programming 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Scala for Backend Engineering & Functional Programming 강의에는 총 4개의 강의가 포함되어 있습니다.

circe를 통한 JSON

http4s는 http4s-circe 모듈을 통해 JSON을 통합하며, 이 모듈은 circe 코덱을 EntityDecoder와 EntityEncoder에 연결합니다. circe는 Scala에서 사실상 표준으로 사용되는 함수형 JSON 라이브러리입니다.

타입에 대한 Encoder와 Decoder 인스턴스를 정의하면 http4s가 전송 형식을 처리합니다.

// build.sbt
// "org.http4s" %% "http4s-circe" % http4sV
// "io.circe"   %% "circe-generic" % circeV

코덱 자동 생성

circe-generic을 사용하면 deriveEncoder/deriveDecoder 또는 @JsonCodec 주석으로 코덱을 자동 생성할 수 있습니다. 생성된 코덱은 케이스 클래스의 필드를 이름에 따라 JSON 키에 매핑합니다.

자동 생성하려면 모든 필드 타입에 대한 코덱이 재귀적으로 필요합니다.

import io.circe.generic.semiauto._

case class User(id: Int, name: String)
implicit val enc = deriveEncoder[User]
implicit val dec = deriveDecoder[User]

circe에서 EntityEncoder 만들기

org.http4s.circe.CirceEntityEncoder._를 임포트하면 circe Encoder가 있는 모든 A에 대해 암시적 EntityEncoder[F, A]가 제공됩니다. 그러면 Ok(user)가 application/json 형식의 JSON으로 직렬화됩니다.

핸들러에서 Json으로 수동 변환할 필요가 없습니다.

import org.http4s.circe.CirceEntityEncoder._

HttpRoutes.of[IO] {
  case GET -> Root / "me" => Ok(User(1, "Ada"))
}

circe에서 EntityDecoder 만들기

반대쪽도 같은 방식입니다. org.http4s.circe.CirceEntityDecoder._를 임포트하면 circe Decoder가 있는 모든 A에 대해 EntityDecoder[F, A]가 제공됩니다. 그러면 req.as[User]가 JSON 본문을 파싱합니다.

두 임포트를 함께 묶은 것이 CirceEntityCodec._입니다.

import org.http4s.circe.CirceEntityDecoder._

case req @ POST -> Root / "users" =>
  req.as[User].flatMap(u => Created(u))

완전한 JSON POST

디코딩과 인코딩을 결합하면 깔끔한 생성 엔드포인트를 만들 수 있습니다. 들어온 JSON을 도메인 타입으로 파싱하고, 비즈니스 로직을 실행한 다음, 결과를 다시 JSON으로 인코딩합니다.

디코딩 실패는 circe 디코더를 통해 422 또는 400으로 나타납니다.

import org.http4s.circe.CirceEntityCodec._

case req @ POST -> Root / "users" =>
  for {
    in  <- req.as[User]
    out <- store.create(in)
    res <- Created(out)
  } yield res

json 보간기

즉석에서 JSON을 만들 때는 io.circe.literal의 circe json 문자열 보간기가 보간된 Scala 값과 함께 Json 값을 직접 생성합니다.

케이스 클래스 없이 작은 응답이나 테스트 픽스처를 만들 때 유용합니다.

import io.circe.literal._

val body = json"""{ "status": "ok", "count": 3 }"""
Ok(body)

사용자 지정 필드 이름

JSON 키가 Scala 필드 이름과 다를 때는 circe-generic-extras의 Configuration을 사용해, 예를 들어 snake_case 방식으로 생성하거나 forProduct2를 사용해 코덱을 직접 작성합니다.

이렇게 하면 API 계약과 내부 이름을 분리할 수 있습니다.

import io.circe.Encoder

implicit val e: Encoder[User] =
  Encoder.forProduct2("user_id", "full_name")(u => (u.id, u.name))

목록 인코딩

circe는 요소 코덱이 존재하면 List, Vector, Option, Map에 대한 코덱을 자동으로 제공합니다. 따라서 컬렉션을 그대로 반환할 수 있습니다.

빈 목록은 []로 인코딩되고, None은 키가 없거나 null로 인코딩됩니다.

import org.http4s.circe.CirceEntityEncoder._

case GET -> Root / "users" =>
  store.all.flatMap(us => Ok(us)) // List[User] -> JSON array

디코딩된 JSON 검증

디코딩하면 문법적으로 유효한 값을 얻지만, 의미 검증은 직접 수행해야 합니다. as 이후에 검사를 실행하고, 유효하지 않으면 BadRequest로 조기에 종료합니다.

명확성을 위해 도메인 불변 조건은 Either를 반환하는 스마트 생성자에 유지합니다.

req.as[User].flatMap { u =>
  if (u.name.nonEmpty) Created(u)
  else BadRequest("name required")
}

JSON으로 오류 응답 보내기

클라이언트가 파싱할 수 있도록 구조화된 오류를 JSON으로 반환합니다. circe 인코더가 있는 오류 케이스 클래스를 정의하고 관련 상태 빌더에 전달합니다.

오류 형식을 일관되게 유지하면 API를 훨씬 쉽게 사용할 수 있습니다.

case class ApiError(code: String, message: String)
implicit val e = deriveEncoder[ApiError]

BadRequest(ApiError("E_NAME", "name required"))

JSON 스트리밍

대규모 컬렉션에서는 버퍼링하는 대신 JSON을 스트리밍할 수 있습니다. jsonEncoderOf와 fs2 Stream[F, A]를 함께 사용하면 JSON 배열을 점진적으로 출력합니다.

fs2의 백프레셔를 활용하므로 큰 결과 집합에서도 메모리 사용량이 일정하게 유지됩니다.

import org.http4s.circe.streamJsonArrayEncoder

case GET -> Root / "feed" =>
  Ok(store.streamAll) // fs2.Stream[IO, Event]

빠른 확인

JSON 본문을 케이스 클래스로 디코딩할 수 있게 하는 임포트를 떠올려 보세요.

복습

http4s-circe로 JSON을 연결했습니다. 코덱을 생성하고, CirceEntityCodec을 임포트한 다음, 완전한 JSON 입출력에 Ok(value) / req.as[A]를 사용했습니다.

목록, 사용자 지정 필드 이름, 구조화된 JSON 오류를 처리했으며, 큰 페이로드를 위한 배열 스트리밍도 살펴보았습니다.

자주 묻는 질문

“JSON 엔드포인트” 강의는 무료인가요?

네 — “JSON 엔드포인트” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Scala for Backend Engineering & Functional Programming 강의 전체를 잠금 해제할 수 있습니다. Scala for Backend Engineering & Functional Programming 강의에는 총 4개의 강의가 포함되어 있습니다.

“JSON 엔드포인트”에서 뭘 배우나요?

http4s와 Circe를 결합해 보세요. 브라우저에서 직접 실행하는 실습 코드로 Scala for Backend Engineering & Functional Programming을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Scala for Backend Engineering & Functional Programming을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Scala for Backend Engineering & Functional Programming은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.

“JSON 엔드포인트” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Scala for Backend Engineering & Functional Programming 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Scala for Backend Engineering & Functional Programming 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 라우트와 HttpRoutes
  2. 요청과 응답
  3. JSON 엔드포인트
  4. 애플리케이션 제공하기
← Scala for Backend Engineering & Functional Programming(으)로 돌아가기