GithubHelp home page GithubHelp logo

Comments (13)

aryairani avatar aryairani commented on July 22, 2024

Good point, I had already forgotten that RhoService != SwaggerSupport.

from rho.

kryptt avatar kryptt commented on July 22, 2024

Here is what I have:

  def systemServices = new SwaggerSupport with core.UserService with core.AuditService {
    override def apiInfo = Info(
      "MY-API",
      my.version,
      "My API".some,
      "terms-conditions".some,
      Contact("[email protected]").some,
      License("MY-LIC", my.licenseUrl).some
    )
  }

similar to the @bryce-anderson 's suggesting in #67, where core.UserService and core.AuditService extend RhoService and not SwaggerSupport. @cencarnacion mentioned a potential drawback to doing it that way, but I can't remember what it was :( ....

All that said, I agree composition should be done without the use of multiple inheritance :)

from rho.

bryce-anderson avatar bryce-anderson commented on July 22, 2024

This is something I'd like to get taken care of. I don't have any specific ideas right now on how to get this done, but I'll be thinking about it in the near future. Any suggestions are very much appreciated.

from rho.

shengc avatar shengc commented on July 22, 2024

is there an eta for adding this feature ? Not able to compose routes coming from different packages through rho forbids a more manageable and thus clearer pattern to organize the code. How about making up a mutable kind of PathTree ? this way, same instance of _tree can be dependency injected into multiple RhoService traits (through def instead of var). Once classes finish the initialization, _tree would contain routes defined from all over the places.

from rho.

bryce-anderson avatar bryce-anderson commented on July 22, 2024

@shengc: no eta right now.

I'm not sure if there are any examples so just in case you haven't tried it, you can use the cake pattern to modularize your code:

trait Routes1 { self: RhoService =>
   ...
}

trait Routes2 { self: RhoService =>
   ...
}

object MyService extends RhoService with SwaggerSupport with Routes1 with Routes2

There shouldn't be a need to make a mutable tree: they can be easily merged immutably. At one point it actually was mutable. If I understand you, you want that to turn the var _tree to a def _tree in the trait but I don't see what that would help. I'm going to admit that is certainly some code smell right now but was hoping to get the alternate patter working. Maybe, as a quick solution while we try and figure this one out for real, we should have a concrete base class with a updateTree like method? That would avoid the initialization of the var issues that come with having vars in traits.

I'm also a bit confused why you would want to use the same tree for multiple RhoServices: this issue is about taking combing multiple RhoServices into a single RhoService.

from rho.

shengc avatar shengc commented on July 22, 2024

@bryce-anderson What I am thinking is pretty much the same as you propose, use the same instance of _tree to let route coming from different places be merged in. Though I personally don't like cake pattern, but have to admit what you give is the only possible way given the current code base.

I think our problem boils down to how can we merge _tree (and swaggerSpec) from different RhoService (with SwaggerSupport). It is not a trivial task IMO. That said, if we can make route append be lazy, meaning instead of actively appending routes to tree during class initialization, we place the routes in a private container inside the class. Now combining two RhoService instances means combining the container from the two. toService method should be modified to be responsible creating the tree instance, appending all route from the container to the tree, and making up the HttpService based on it. Now everything is immutable, and we don't need to care/worry if tree is mutable or a var, since it is always created within the scope of toService method, and never will have a chance to be leaked.

from rho.

bryce-anderson avatar bryce-anderson commented on July 22, 2024

That seems like a reasonable proposal for merging trees, but the important part is merging services like the SwaggerSupport. What would we do with a situation that needs to combine 2 swagger services and one intentionally non-swagger service? Even just merging two swagger services is non-trivial in that we now have two trees that need merging. Then what about HAL? The problem baloons pretty fast.

I've been thinking about this problem as a situation akin to the http4s (among others, its not a very novel idea) attributes. A 'service' will have an attribute key that knows what to do with the routes its fed. When multiple services of the same type are merged, they should know how to merge their interesting bits. The part I've not thought hard about is what is the best way to allow them to modify the resulting tree? Just let them do it sequentially in terms of the first (maybe last?) occurrence of a service?

from rho.

shengc avatar shengc commented on July 22, 2024

This is the append method in RhoService

protected def append[T <: HList](route: RhoRoute[T]): Unit =
  __tree = __tree.appendRoute(route)

This is the append method overriden in SwaggerSupport

override protected def append[T <: HList](rr: RhoRoute[T]): Unit = {
  super.append(rr)
  val sb = new SwaggerModelsBuilder(swaggerFormats)    
  swaggerSpec = sb.mkSwagger(apiInfo, rr)(swaggerSpec)
}

My proposal essentially is to delay inserting rr: RhoRoute[T] into _tree, and building the swaggerSpec with in case SwaggerSupport is mixed in. In other words, I would move the the body of append to toService, and accumulate RhoRoute in a container. When toService is called, all RhoRoute are inserted into the _tree and building up the swaggerSpec in case of SwaggerSupport. You don't need to worry whether routes come from one or multiple RhoService, as long as we can find a way to combine the container(s). This solution has the least impact on the rest of the code, and avoids the complicated logic of tree merging and swagger spec merging as well.

from rho.

bryce-anderson avatar bryce-anderson commented on July 22, 2024

@shengc, I think what you're proposing is certainly a step in the right direction although I don't think its the end of the story.

Is this something we want to try and get done before the next release? I suspect it will be pretty fast but its hard to say until diving in and I'm really busy with work this week so I can't make any promises with regard to getting it done.

from rho.

shengc avatar shengc commented on July 22, 2024

@bryce-anderson I can take a look at it (warning, no guarantee of ETA), and submit a PR for review.

Maybe it is better to try this first in a branch instead of going against master ?

from rho.

bryce-anderson avatar bryce-anderson commented on July 22, 2024

Deal. I've made a branch, issue/48, to work against.

from rho.

shengc avatar shengc commented on July 22, 2024

Cool - having some house work this week and have to rely on a laptop off my hours. Probably will start around next week.

from rho.

bryce-anderson avatar bryce-anderson commented on July 22, 2024

closed by 256b4b0.

from rho.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.