Soru Scala'da sprey kullanarak basit bir json REST sunucusu yaz


Aşağıdaki yolları destekleyen scala'da sprey kullanarak basit bir json REST sunucusu uygulamak istiyorum:

GET /foo => return a list of case class objects in json format
POST /bar => read a json into a case class object and perform some computation

Temel başlangıç ​​kodum şu şekildedir:

import spray.routing.SimpleRoutingApp
import spray.can.Http
import akka.actor.ActorSystem
import akka.actor.Props
import akka.io.IO
import scala.collection.JavaConversions
import com.fasterxml.jackson.databind.ObjectMapper

object SprayTest extends App with SimpleRoutingApp {
  implicit val system = ActorSystem("my-system")
  val mapper = new ObjectMapper

  case class Foo(a: String, b: Int)
  case class Bar(c: Long, d: String)

  startServer(interface = "localhost", port = 8080) {
    get {
      path("foo") {
        complete {
          val c = listOfFoo()
          mapper.writeValueAsString(c)
        }
      }
    } ~ post {
      path("bar") {
        val bar: Bar = ???
        complete {
          "???"
        }
      }
    }
  }
}

Bu kodla bildiğim en önemli iki açık sorun şunlardır:

  1. Jackson'a bağlıyım ama internette arama yapmak, sprey gibi basit vaka nesnelerini veya vaka nesneleri listelerini serileştirmek ve serileştirmek için bir şekilde desteklenmelidir.

  2. "En iyi", "iddi" ve "özlü" ve "özlü" yollardan emin değilim. Bu durumda, yazı isteği nesnesinde içerik hesaplaması yapabilmem için json'a gönderdim.

En iyi yaklaşımı bilen var mı? Otomatik marshalling yapmak için bir yolu var, bu yüzden ben gibi bir şey yürütmek complete { caseObject } ve sahip caseObject otomatik olarak json dönüştürmek (ve POST yöntemi tanımlayarak tersi)?


21
2018-06-06 23:29


Menşei




Cevaplar:


Kesinlikle sprey json kullanın. Genellikle veri modellerini kendi dosyalarına ayırırsınız:

import spray.json._

case class Foo(a: String, b: Int)
case class Bar(c: Long, d: String)

object FooBarJsonProtocol extends DefaultJsonProtocol{
    implicit val fooFormat = jsonFormat2(Foo)
    implicit val barFormat = jsonFormat2(Bar)
}

Sonra rotada

    import FooBarJsonProtocol._
    ...
    get {
      path("foo") {
        complete {
          listOfFoo() //with the implicit in scope this will serialize as json
        }
      }
    } ~ post {
      path("bar") {
        entity(as[Bar]) { bar =>  //extract json Bar from post body
          complete(bar) //serialize bar to json (or whatever processing you want to do)
        }
      }
    }
  }

20
2018-06-07 03:24



İçinde spray-json 1.3.3 ithalatı önemli import spray.httpx.SprayJsonSupport._ - Core
Gangstead - Çok teşekkür ederim! çok yararlı!!! - Briksins
Sipariş / ithalat da sakının. - o_nix


Bu sorunun neden reddedildiğini hayal bile edemiyorum - özgül ve iyi ifade edilmiş gibi görünüyor.

Bulması biraz zor, ancak Sprey dokümanlar kapsamı vaka sınıfı çıkarma Sprey Yönlendirme / İleri Konular altında. Burada açıklamalarını tekrarlamak anlamsız olurdu, ama temelde kullanmak istiyorsun as[Foo] HTTP içeriğini nesnelere serpiştirmek için. entity Direktif bu şekilde gösterildiği gibi, bir istek gövdesi için bunu yapmak için kullanılabilir püskürtme yöneltme DSL'sinin daha uzun bir örneği. mapTo (aynı örnekte kullanılır), muhtemelen, yanıt için bir nesneyi serileştirmek istediğiniz şeydir.

JSON için, muhtemelen ayrı ayrı kullanmak daha kolay olurdu Sprey-JSON kütüphane, tıpkı kendi sınıflandırma mekanizmalarına tıkandığından, ama biraz çabala istediğiniz bir şeyle evlenebileceğinizi düşünüyorum. Spray-JSON, bir hat tutkalı olan bir kılıf sınıfını idare edebilir.

Bu arada, çizgi val bar: Bar = ??? Örnek kodunuzda, güzergahın tanımlandığı zamanda, bir istek geldiğinde değil, muhtemelen istediğiniz gibi yürütülecektir. Lütfen okuyun DSL Yapısını Anlamak Sprey yönlendirme dokümanlarının bölümü.


7
2018-06-07 02:37





Anladım teşekkürler, işte benim cevabım

import spray.routing._
import spray.json._
import spray.httpx._
import spray.http._


case class UserLogin(username: String, password: String)

object UserLoginJsonSupport extends DefaultJsonProtocol with SprayJsonSupport {
   implicit val PortofolioFormats = jsonFormat2(UserLogin)
}

import UserLoginJsonSupport._


trait UserAccountsServiceAPI extends HttpService{       
    val UserAccountsServiceRouting = {
      path("api" / "userservice" ) {   
        post {
           entity(as[UserLogin]) { userLogin =>
                println("->"+userLogin.username)
                println("->"+userLogin.password)
                complete(userLogin.username)
           }
        }
      }
   }
}

Curl uygulaması ile http isteğim

curl -i 'http://localhost:8080/api/userservice' -X POST -H "Content-Type: application/json" -d '{"username": "admin", "password": "pwd"}'

2
2017-10-20 21:35