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