Code

The network stack — build.gradle.kts, DTO, PicaApi

Three files in the code column as tabs, in the order you build them: build.gradle.ktsMenuItemDto.ktPicaApi.kt. The libraries come first — nothing else compiles without them.

1. build.gradle.kts (modify) — add the network stack: the kotlin.serialization plugin and the Retrofit + kotlinx-serialization dependencies. "Stack when needed" — we add these the moment we need them, not before. Everything from lesson 1 stays; the diff shows only the new lines.

2. MenuItemDto.kt (data) — the wire model. It mirrors the server JSON exactly, plus a translator to the domain:

@SerialName("price_cents") val priceCents: Int   // JSON is snake_case; Kotlin isn't
// …
fun MenuItemDto.toDomain(): MenuItem = MenuItem(price = priceCents / 100.0, /* … */)
  • @SerialName("price_cents") links the JSON field price_cents to Kotlin's priceCents.
  • toDomain() converts cents → euros. The UI sees a clean MenuItem (like lesson 2), unaware of cents or JSON.

3. PicaApi.kt (network) — the service interface. Retrofit turns @GET("menu") suspend fun getMenu(): List<MenuItemDto> into a working HTTP client. Just the menu for now; other endpoints join in their lessons.

Verify. The project compiles. PicaApi and MenuItemDto aren't called anywhere yet — we wire them in the next step.

Tip. Why a separate DTO instead of just annotating MenuItem? Because the JSON shape belongs to the server (cents, snake_case), while the UI model belongs to you. Separating them means a server change doesn't break your whole UI — you only fix toDomain().