CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
Scala 语言入门/课时/综合练习
RawBlame
课时目录12 节

Scala 语言入门

  1. 01Scala 是什么
  2. 02基础语法
  3. 03OOP 与模式匹配
  4. 04集合与高阶函数
  5. 05函数式编程
  6. 06类型系统
  7. 07构建工具
  8. 08后端框架
  9. 09数据与 JSON
  10. 10测试
  11. 11并发与流
  12. 12综合练习

综合练习

Akka HTTP 迷你 API + Circe JSON。

40 分钟

综合练习

本课整合前 11 课:用 sbt 搭建项目,实现 Pekko HTTP 迷你 API + Circe JSON,编写 ScalaTest,对照 /roadmaps/scala 验收本 track。

学习目标

  • 搭建标准 sbt 项目布局
  • 实现带 CRUD 的 REST API(内存存储即可)
  • 用 Circe 序列化响应,ScalaTest 覆盖核心逻辑
  • 对照 Spring Boot 同功能 API 的设计差异

核心概念

项目结构

bookmark-api/
├── build.sbt
├── project/build.properties
└── src/
    ├── main/scala/
    │   ├── Main.scala
    │   ├── model.scala
    │   ├── store/MemoryStore.scala
    │   └── routes/BookmarkRoutes.scala
    └── test/scala/
        └── BookmarkSuite.scala

main 启动 HTTP;store 放内存实现;routes 放 Pekko HTTP 路由。

REST API 需求

方法路径说明
GET/health返回 {"status":"ok"}
GET/api/bookmarks列表
POST/api/bookmarks创建 {"url","title"}
GET/api/bookmarks/:id详情,404 若不存在
DELETE/api/bookmarks/:id删除

核心代码片段

// model.scala
case class Bookmark(id: Long, url: String, title: String)
case class CreateBookmark(url: String, title: String)

// MemoryStore.scala
class MemoryStore:
  private var nextId = 1L
  private var data = Map.empty[Long, Bookmark]

  def list: List[Bookmark] = data.values.toList.sortBy(_.id)
  def get(id: Long): Option[Bookmark] = data.get(id)
  def create(url: String, title: String): Bookmark =
    val b = Bookmark(nextId, url, title)
    nextId += 1
    data = data + (b.id -> b)
    b
  def delete(id: Long): Boolean =
    if data.contains(id) then data = data - id; true else false

// BookmarkRoutes.scala — POST 解析 Circe JSON,返回 JSON 响应
import io.circe.syntax.*
import io.circe.generic.auto.*

post {
  entity(as[String]) { body =>
    decode[CreateBookmark](body) match
      case Right(req) =>
        val b = store.create(req.url, req.title)
        complete(StatusCodes.Created, b.asJson.noSpaces)
      case Left(err) =>
        complete(StatusCodes.BadRequest, err.getMessage)
  }
}

测试与验收

class BookmarkSuite extends AnyFunSuite:
  test("create and list") {
    val s = MemoryStore()
    s.create("https://a.com", "A")
    assert(s.list.size == 1)
  }
  test("delete missing returns false") {
    val s = MemoryStore()
    assert(!s.delete(99L))
  }
  • sbt test 全部通过
  • curl 验证 CRUD 与 JSON 格式
  • sbt run 启动服务,health 返回 200
  • 回顾 /roadmaps/scala 已完成节点

扩展方向

  • 接入 PostgreSQL(Doobie)替代内存 store
  • 添加 ZIO 或 Future 异步边界
  • Docker 容器化(见 docker-essentials)

与 Java 对照

同一 API 在 spring-boot-essentials 用 @RestController + Jackson 实现,体会:

  • Scala 路由 DSL vs Spring 注解
  • Circe vs Jackson 配置
  • 编译期类型安全 vs Spring 运行时反射

练习

  • 完成上述 CRUD 与至少 3 个测试
  • 为错误响应统一 JSON 结构 {"error":"..."}
  • 通读本 track 12 课并在路线图勾选节点

小结

本 track 覆盖 Scala 从语法到可测试 HTTP 服务的核心路径。 继续深入可探索 Spark、ZIO 或阅读 Pekko 文档。完整路径见 /roadmaps/scala 与 scala-essentials。

加载本节练习…
← 上一课并发与流