scala - Spray.io 路由可以拆分成多个 "Controllers"吗?

标签 scala spray

我还没有找到将 Spray.io 路由拆分为多个文件的可靠示例或结构。我发现我的路由的当前结构将变得非常繁琐,对于一个非常简单的 REST API 应用程序,将它们抽象为不同的“ Controller ”会很好。

文档似乎没有太大帮助:http://spray.io/documentation/spray-routing/key-concepts/directives/#directives

这是我到目前为止所拥有的:

class AccountServiceActor extends Actor with AccountService {

  def actorRefFactory = context

  def receive = handleTimeouts orElse runRoute(demoRoute)

  def handleTimeouts: Receive = {
    case Timeout(x: HttpRequest) =>
      sender ! HttpResponse(StatusCodes.InternalServerError, "Request timed out.")
  }
}


// this trait defines our service behavior independently from the service actor
trait AccountService extends HttpService {

  val demoRoute = {
    get {
      path("") {
        respondWithMediaType(`text/html`) { // XML is marshalled to `text/xml` by default, so we simply override here
          complete(index)
        }
      } ~
      path("ping") {
        complete("PONG!")
      } ~
      path("timeout") { ctx =>
        // we simply let the request drop to provoke a timeout
      } ~
      path("crash") { ctx =>
        throw new RuntimeException("crash boom bang")
      } ~
      path("fail") {
        failWith(new RuntimeException("aaaahhh"))
      } ~
      path("riaktestsetup") {
        Test.setupTestData
        complete("SETUP!")
      } ~
      path("riaktestfetch" / Rest) { id =>
        complete(Test.read(id))
      }
    }
  }
}

感谢您对此的帮助!

最佳答案

我个人将其用于大型 API:

class ApiActor extends Actor with Api {
  override val actorRefFactory: ActorRefFactory = context

  def receive = runRoute(route)
}

/**
 * API endpoints
 *
 * Individual APIs are created in traits that are mixed here
 */
trait Api extends ApiService
  with AccountApi with SessionApi
  with ContactsApi with GroupsApi
  with GroupMessagesApi with OneToOneMessagesApi
  with PresenceApi
  with EventsApi
  with IosApi
  with TelephonyApi
  with TestsApi {
  val route = {
    presenceApiRouting ~
    oneToOneMessagesApiRouting ~
    groupMessagesApiRouting ~
    eventsApiRouting ~
    accountApiRouting ~
    groupsApiRouting ~
    sessionApiRouting ~
    contactsApiRouting ~
    iosApiRouting ~
    telephonyApiRouting ~
    testsApiRouting
  }
}

我建议将最常见的路线放在首位,然后使用 pathPrefix尽快在子路由中,以便减少 Spray 为每个传入请求运行的测试数量。

您会在下面找到一条我认为经过优化的路线:
  val groupsApiRouting = {
    pathPrefix("v3" / "groups") {
      pathEnd {
        get {
          traceName("GROUPS - Get joined groups list") { listJoinedGroups }
        } ~
        post {
          traceName("GROUPS - Create group") { createGroup }
        }
      } ~
      pathPrefix(LongNumber) { groupId =>
        pathEnd {
          get {
            traceName("GROUPS - Get by ID") { getGroupInformation(groupId) }
          } ~
          put {
            traceName("GROUPS - Edit by ID") { editGroup(groupId) }
          } ~
          delete {
            traceName("GROUPS - Delete by ID") { deleteGroup(groupId) }
          }
        } ~
        post {
          path("invitations" / LongNumber) { invitedUserId =>
            traceName("GROUPS - Invite user to group") { inviteUserToGroup(groupId, invitedUserId) }
          } ~
          path("invitations") {
            traceName("GROUPS - Invite multiple users") { inviteUsersToGroup(groupId) }
          }
        } ~
        pathPrefix("members") {
          pathEnd {
            get {
              traceName("GROUPS - Get group members list") { listGroupMembers(groupId) }
            }
          } ~
          path("me") {
            post {
              traceName("GROUPS - Join group") { joinGroup(groupId) }
            } ~
            delete {
              traceName("GROUPS - Leave group") { leaveGroup(groupId) }
            }
          } ~
          delete {
            path(LongNumber) { removedUserId =>
              traceName("GROUPS - Remove group member") { removeGroupMember(groupId, removedUserId) }
            }
          }
        } ~
        path("coverPhoto") {
          get {
            traceName("GROUPS - Request a new cover photo upload") { getGroupCoverPhotoUploadUrl(groupId) }
          } ~
          put {
            traceName("GROUPS - Confirm a cover photo upload") { confirmCoverPhotoUpload(groupId) }
          }
        } ~
        get {
          path("attachments" / "new") {
            traceName("GROUPS - Request attachment upload") { getGroupAttachmentUploadUrl(groupId) }
          }
        }
      }
    }
  }

关于scala - Spray.io 路由可以拆分成多个 "Controllers"吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14653526/

相关文章:

scala - 还有什么是Scala惯用: trait TraitA extends TraitB or trait TraitA { self: TraitB => }

scala - 自定义 Spray.io 指令来验证请求 header 值

scala - 找不到参数 marshaller : spray. httpx.marshalling.ToResponseMarshaller 的隐式值

scala - Akka Http : Exceeded configured max-open-requests value of [32]

eclipse - 使用 Eclipse 深色主题的 Scala 项目看起来很糟糕

scala - Scala: curry 构造函数

scala - 在 Slick 2.0 中插入后返回 AutoInc ID

scala - 如何重命名 Scala 中 count() 函数生成的列

scala - 如何在单个路由中解码 POST 参数和 JSON 正文?

sbt - 没有 Play 的最小 sbt-web 管道