volumen por plasticos moldeo libros inyeccion farmacopea edicion curso argentina scala spray

scala - por - farmacopea argentina 7 edicion volumen 1



¿Se pueden dividir las rutas de Spray.io en múltiples "Controladores"? (3)

No he encontrado un ejemplo o estructura sólida para dividir las rutas de Spray.io en varios archivos. Estoy descubriendo que la estructura actual de mis rutas se va a volver muy engorrosa, y sería bueno abstraerlas en diferentes "Controladores" para una aplicación API REST muy simple.

Los documentos no parecen ayudar demasiado: http://spray.io/documentation/spray-routing/key-concepts/directives/#directives

Esto es lo que tengo hasta ahora:

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)) } } } }

Gracias por ayudar en esto!


Intenté de esta manera desde el fragmento de código anterior, el formato básico y las obras.

import akka.actor.ActorSystem import akka.actor.Props import spray.can.Http import akka.io.IO import akka.actor.ActorRefFactory import spray.routing.HttpService import akka.actor.Actor /** * API endpoints * * Individual APIs are created in traits that are mixed here */ trait Api extends ApiService with UserAccountsService { val route ={ apiServiceRouting ~ accountsServiceRouting } } trait ApiService extends HttpService{ val apiServiceRouting={ get{ path("ping") { get { complete { <h1>pong</h1> } } } } } } trait UserAccountsService extends HttpService{ val accountsServiceRouting={ path("getAdmin") { get { complete { <h1>AdminUserName</h1> } } } } } class ApiActor extends Actor with Api { override val actorRefFactory: ActorRefFactory = context def receive = runRoute(this.route) } object MainTest extends App { // we need an ActorSystem to host our application in implicit val system = ActorSystem("UserInformaitonHTTPServer") // the handler actor replies to incoming HttpRequests val handler = system.actorOf(Props[ApiActor], name = "handler") // starting the server IO(Http) ! Http.Bind(handler, interface = "localhost", port = 8080) }


Puede combinar rutas de diferentes "Controladores" usando ~ combinator.

class AccountServiceActor extends Actor with HttpService { def actorRefFactory = context def receive = handleTimeouts orElse runRoute( new AccountService1.accountService1 ~ new AccountService2.accountService2) def handleTimeouts: Receive = { case Timeout(x: HttpRequest) => sender ! HttpResponse(StatusCodes.InternalServerError, "Request timed out.") } } class AccountService1 extends HttpService { val accountService1 = { get { path("") { respondWithMediaType(`text/html`) { // XML is marshalled to `text/xml` by default, so we simply override here complete(index) } } } } class AccountService2 extends HttpService { val accountService2 = { get { path("someotherpath") { respondWithMediaType(`text/html`) { // XML is marshalled to `text/xml` by default, so we simply override here complete(index) } } } }


Yo personalmente uso esto para grandes APIs:

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 } }

Recomendaría poner primero las rutas más comunes y usar pathPrefix tan pronto como pueda en las pathPrefix , para reducir la cantidad de pruebas que Spray ejecuta para cada solicitud entrante.

A continuación encontrará una ruta que creo que está optimizada:

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) } } } } } }