Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't Use API Factory Functions for Namespacing Purposes #64

Open
michaelahlers opened this issue May 17, 2017 · 3 comments
Open

Can't Use API Factory Functions for Namespacing Purposes #64

michaelahlers opened this issue May 17, 2017 · 3 comments

Comments

@michaelahlers
Copy link

michaelahlers commented May 17, 2017

In a similar vein as #7, I wish to have functions (or values) on my auto-wired API that serve as namespaces for more specific functionality. The following variant on the Minimal Example illustrates the intent:

import autowire._
import upickle._

trait MySpecificApi {
  def doThing(i: Int, s: String): Seq[String]
}

object MySpecificApiImpl extends MySpecificApi {
  def doThing(i: Int, s: String) = Seq.fill(i)(s)
}

trait MyApi {
  def mySpecificApi: MySpecificApi
}

object MyApiImpl extends MyApi {
  override val mySpecificApi: MySpecificApi = MySpecificApiImpl
}

object MyServer extends autowire.Server[String, upickle.Reader, upickle.Writer]{
  def write[Result: Writer](r: Result) = upickle.write(r)
  def read[Result: Reader](p: String) = upickle.read[Result](p)

  val routes = MyServer.route[MyApi](MyApiImpl)
}

object MyClient extends autowire.Client[String, upickle.Reader, upickle.Writer]{
  def write[Result: Writer](r: Result) = upickle.write(r)
  def read[Result: Reader](p: String) = upickle.read[Result](p)

  override def doCall(req: Request) = {
    println(req)
    MyServer.routes.apply(req)
  }
}

MyClient[MyApi].mySpecificApi.doThing(3, "lol").call().foreach(println)

This fails to compile with an error similar to:

Error:(27, 38) A$A36.this.MySpecificApi does not take parameters
  val routes = MyServer.route[MyApi](MyApiImpl)
                                    ^

Is this supported, and—in any case—is there any other preferred approach?

@michaelahlers
Copy link
Author

Is this duplicative of #22?

@cornerman
Copy link
Contributor

I also wanted to separate my Apis and went for this approach (maybe also works for you?):

trait MySpecificApi {
  def doThing(i: Int, s: String): Seq[String]
}

trait My MyOtherApi {
  def doOtherThing(): String
}

// server
object MySpecificApiImpl extends MySpecificApi {...}
object MyOtherApiImpl extends MyOtherApi {...}
val route = MyServer.route[MySpecificApi](MySpecificApiImpl) orElse MyServer.route[MyOtherApi](MyOtherApiImpl)

// client
object MyApis {
  val specificApi = MyClient[MySpecificApi]
  val otherApi = MyClient[MyOtherApi]
}

@michaelahlers
Copy link
Author

@cornerman, that's a great suggestion. I'll give that a whirl!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants