REST in Scala

¿qUÉ ES SPRAY?


  • Stack embebible para aplicaciones Akka (Scala).

  • Foco: desarrollo de capas de integración REST/HTTP

  • Filosofía: set de librerías (toolkit), no un framework (full stack).

  • Server- and client-side.
  • Mathias Doenitz


    Lead developer of Spray.io, Akka committer,

    passionate Scala-ista

    AKKA

    Akka es un toolkit para construir sistemas
    distribuidos, de alta concurrencia y con
    tolerancia a fallos sobre la JVM.

    Actores: entidades livianas de concurrencia
    que se comunican entre sí mediante el envío y
    recepción de mensajes

    Foco: flujo de mensajes a través del sistema,
    en vez de operaciones de bajo
    nivel (threads, locks, socket IO, etc.)

    ¿pOR QUÉ SPRAY?


    Java Servlets? Netty, Restlet, Undertow, ... ?

    • Servlet containers?
    • Configuraciones XML?
    • Modelo de datos mutables?
    • Java collections?
    • Capas de adaptación?
    • Type-safety?

    ¡Queremos!


    SCALA + AKKA

    • `Case class`-based model
    • Actor-based APIs (message protocols)
    • Functions as values
    • Scala/Akka Futures
    • Scala collections
    • Type classes
    • Type safety

    SPRAY: scala + AKKA


    • Complemetamente escrito en
      Scala (sin wrappings de Java libraries).
       
    • Akka Actors como componentes principales  
      en todas las capas.
    • Core API style: message protocol.   
    • Completamente async y non-blocking.   

    rápido + liviano + modular + testeable

    Componentes


    además: spray-httpx, spray-caching, spray-testkit,  ...

    spray-http (data model)


    • High-level abstractions para representar
      casi todos los componentes HTTP.
    • `Case class`-based data model
    • Fully immutable, little logic  
    • Instancias predefinidas para casi todos los tipos
      de media types, status codes, encodings, charsets,
      cache-control directives, etc.

    • Abierto para extender  (ej: custom media types)

    HTTP MODEL: quiero ver el código!

    case class HttpRequest(
      method: HttpMethod = HttpMethods.GET,
      uri: Uri = Uri./,
      headers: List[HttpHeader] = Nil,
      entity: HttpEntity = HttpEntity.Empty,
      protocol: HttpProtocol = HttpProtocols.`HTTP/1.1`
    ) extends HttpMessage
    case class HttpResponse(
    status: StatusCode = StatusCodes.OK, entity: HttpEntity = HttpEntity.Empty, headers: List[HttpHeader] = Nil, protocol: HttpProtocol = HttpProtocols.`HTTP/1.1` ) extends HttpMessage

    spray-can


    • Provee un servidor y un cliente de HTTP
      de bajo nivel, livianos y de alta performance.
    • APIs basadas en Actores que utilizan Mensajes
      para interactuar entre las distintas capas.
    • Soporte de conecciones concurrentes  masivas .
    • HTTP pipelining.
    • Chunked messages (streaming).
    • Encriptación SSL/TLS

    io stack


    akka-io: cierra la brecha entre
    Java NIO y los Actores de Akka.

    spray-routing


    • DSL interno para definir la interfaz HTTP
      de la aplicación.
    • Directivas: pequeños y simples bloques
      de construcción. 
    • Altamamente componible.
    • Type-safe, pero flexible.
    • Mucho más que routing: definicion
      de comportamiento.

    SPRAY-ROUTING: quiero ver el código!


    class MyServiceActor extends HttpServiceActor {
      def receive = runRoute {
        path("order" / IntNumber) { id =>
          get {
            complete {
              "Received GET request for order " + id
            }
          } ~
          put {
            complete {
              "Received PUT request for order " + id
            }
          }
        }
      }
    }

    DISEÑO: API LAYER


    REST API Layer: interfaz HTTP construida
    sobre nuestra aplicación (existente, o no).

    API LAYER: responsabilidades


    • Definición de rutas basadas en una
      arquitectura  REST: métodos, path,
      media-types, etc.
    • Unmarshalling / marshalling.
    • Encoding / decoding (compresión).
    • Autenticación / autorización.
    • Caching y static content.
    • RESTful error handling.

    Ejemplo

    Buenas prácticas


    • No realizar operaciones bloqueantes
      dentro de las rutas.
    • Mantener la estructura de las rutas
      limpia y legible.
    • Extraer lógica a directivas personalizadas.
    • La capa de API debe depender de la
      capa de lógica de negocio, no al revés.

    hay más...


    • Request/response streaming
    • Testing routes
    • Client-side APIs
    • JSON support
    • ...

    ¿qué sigue?


    • Akka-http: sucesor de Spray (se suma
      al stack de Akka y Typesafe)
    • Uso de Reactive Streams y Async Boundaries
    • Integración de Play con Akka-http
      como módulo HTTP principal del stack.
    • Mejoras y nuevos features: Websockets, etc.

    referencias

    ¡Gracias!

    Spray

    By Leonardo Regnier