2014-05-15 5 views
9

जब मैं एक RESTful API विकसित करने के लिए Spray.io का उपयोग कर रहा हूं, तो मुझे अपने एप्लिकेशन को कैसे व्यवस्थित करना चाहिए?Spray.io के साथ एक विश्वसनीय API को कैसे व्यवस्थित करें?

मैंने पहले से ही स्प्रे एप्लिकेशन को विभाजित करने के तरीके पर this answer देखा है, लेकिन मैं इससे संतुष्ट नहीं हूं, क्योंकि यह "प्रति अभिनेता प्रति अनुरोध" दृष्टिकोण का उपयोग नहीं करता है। क्या मैं पथ के आधार पर अपने आवेदन में अन्य अभिनेताओं से रूट अभिनेता से अनुरोध भेज सकता हूं और इन कलाकारों के अंदर, संबंधित मार्गों को परिभाषित कर सकता हूं?

धन्यवाद

उत्तर

8

आप कर सकते हैं एक से दूसरे अभिनेता से निश्चित रूप से आगे अनुरोध, पथ या जो कुछ भी पर आधारित है। मेरी उदाहरण परियोजना की जाँच करें (जो एक उदाहरण परियोजना का एक कांटा का एक कांटा है):

https://github.com/gangstead/spray-moviedb/blob/master/src/main/scala/com/example/routes/ApiRouter.scala

मुख्य अभिनेता कि अन्य अभिनेताओं कि प्रत्येक सेवा को संभालने के लिए सभी अनुरोधों और उन्हें रूट प्राप्त से प्रासंगिक कोड:

def receive = runRoute { 
    compressResponseIfRequested(){ 
     alwaysCache(simpleCache) { 
     pathPrefix("movies") { ctx => asb.moviesRoute ! ctx } ~ 
     pathPrefix("people") { ctx => asb.peopleRoute ! ctx } 
     } ~ 
     pathPrefix("login") { ctx => asb.loginRoute ! ctx } ~ 
     pathPrefix("account") { ctx => asb.accountRoute ! ctx } 
    } 
    } 

और उदाहरण फिल्में मार्ग के लिए:

def receive = runRoute { 
    get { 
     parameters('query, 'page ? 1).as(TitleSearchQuery) { query => 
     val titleSearchResults = ms.getTitleSearchResults(query) 
     complete(titleSearchResults) 
     }~ 
     path(LongNumber) { movieId => 
     val movie = ms.getMovie(movieId) 
     complete(movie) 
     }~ 
     path(LongNumber/"cast") { movieId => 
     val movieCast = ms.getMovieCast(movieId) 
     complete(movieCast)  
     }~ 
     path(LongNumber/"trailers") { movieId => 
     val trailers = ms.getTrailers(movieId) 
     complete(trailers)  
     }   
    } 
    } 
+0

के माध्यम से विशिष्ट उपयोगकर्ता/कनेक्शन के लिए tions मैं यहां आपका उदाहरण देख रहा था और देखा कि आप सीडीआई का उपयोग करते हैं। किसी भी विशेष कारण के लिए आपने इसका उपयोग क्यों किया? – EdMelo

+0

सीडीआई द्वारा आप निर्भरता इंजेक्शन का मतलब है? – Gangstead

+0

हां।/* स्टैकओवरफ्लो को अधिक वर्णों की आवश्यकता होती है ... */ – EdMelo

0

मैं पहली पूर्ण बाकी परियोजना बनाने के साथ एक बहुत संघर्ष कर रहा था। मैंने जो उदाहरण पाया है वह हैलो वर्ल्ड लेवल पर ... मैंने कुछ ब्लॉग पढ़े हैं, कुछ टिप्पणियां हैं और मैंने उदाहरण प्रोजेक्ट बनाने का फैसला किया है। यह स्केला/अक्का/स्प्रे/mysql पर आधारित है

यह WebSocket ग्राहकों को सूचित करने के कि डेटा बदला गया था आदि आप https://github.com/vixxx123/scalasprayslickexample

यहाँ पर यह भी देख सकते हैं के साथ पूर्ण काम कर उदाहरण है कि इस परियोजना से मार्ग का नमूना कोड है :

val personCreateHandler = actorRefFactory.actorOf(RoundRobinPool(2).props(Props[CreateActor]), s"${TableName}CreateRouter") 
val personPutHandler = actorRefFactory.actorOf(RoundRobinPool(5).props(Props[UpdateActor]), s"${TableName}PutRouter") 
val personGetHandler = actorRefFactory.actorOf(RoundRobinPool(20).props(Props[GetActor]), s"${TableName}GetRouter") 
val personDeleteHandler = actorRefFactory.actorOf(RoundRobinPool(2).props(Props[DeleteActor]), s"${TableName}DeleteRouter") 

val userRoute = 
    pathPrefix("person") { 
     pathEnd { 
      get { 
       ctx => personGetHandler ! GetMessage(ctx, None) 
      } ~ 
      post { 
       entity(as[Person]) { 
        entity => 
         ctx => personCreateHandler ! CreateMessage(ctx, entity) 
       } 
      } 
     } ~ 
     pathPrefix (IntNumber){ 
      entityId => { 
       pathEnd { 
        get { 
         ctx => personGetHandler ! GetMessage(ctx, Some(entityId)) 
        } ~ put { 
         entity(as[Person]) { entity => 
          ctx => personPutHandler ! PutMessage(ctx, entity.copy(id = Some(entityId))) 
         } 
        } ~ delete { 
         ctx => personDeleteHandler ! DeleteMessage(ctx, entityId) 
        } ~ patch { 
         ctx => personPutHandler ! PatchMessage(ctx, entityId) 
        } 
       } 
      } 
     } 
    } 

और अभिनेता हैंडलर बनाने से नमूना:

override def receive: Receive = { 

    case CreateMessage(ctx, person) => 

     val localCtx = ctx 
     connectionPool withSession { 
     implicit session => 
      try { 
      val resId = PersonsIdReturning += person 
      val addedPerson = person.copy(id = Some(resId.asInstanceOf[Int])) 
      localCtx.complete(addedPerson) 
      publishAll(CreatePublishMessage(TableName, localCtx.request.uri + "/" + addedPerson.id.get, addedPerson)) 
      L.debug(s"Person create success") 
      } catch { 
      case e: Exception => 
       L.error(s"Ups cannot create person: ${e.getMessage}", e) 
       localCtx.complete(e) 
      } 
     } 
    } 

अभी भी दो महत्वपूर्ण बातें याद आ रही हैं: OAuth2 और notifica धक्का websocket

संबंधित मुद्दे