www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Vibe.d rest & web service?

reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
Is it possible to have some urls routed to serve content and some 
to receive JSON in the same class? Basically I want:

shared static this()
{
     auto router = new URLRouter;
     auto a = new MyInterface;
     router.registerWebInterface(new MyInterface); //?? selective 
combination
     router.registerRestInterface(new MyInterface); //??
     auto settings = new HTTPServerSettings;
     settings.port = 8080;
     settings.bindAddresses = ["::1","127.0.0.1"];
     listenHTTP(settings, router);
}

class MyInterface
{
     SomeData[] items;
     // Get
     void index()
     {
         render!("index.dt");
     }
     // Get
     void getPage()
     {
         render!("page.dt", items);
     }

     // REST -> receive d as JSON.
     void postGiveMeData(SomeData d)
     {
         synchronized
         {
             items ~= d;
         }
     }
}
Feb 07 2018
next sibling parent reply Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Wednesday, 7 February 2018 at 17:04:13 UTC, Nicholas Wilson 
wrote:
 Is it possible to have some urls routed to serve content and 
 some to receive JSON in the same class?
This seems unlikely to me, the function signature doesn't provide a way to distinguish between REST and not. I'm also not sure it is necessary, you can certainly have multiple class which provide REST and Web endpoints. You can even dynamically build routes within a route.
Feb 07 2018
parent Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Wednesday, 7 February 2018 at 17:57:09 UTC, Jesse Phillips 
wrote:
 On Wednesday, 7 February 2018 at 17:04:13 UTC, Nicholas Wilson 
 wrote:
 Is it possible to have some urls routed to serve content and 
 some to receive JSON in the same class?
This seems unlikely to me, the function signature doesn't provide a way to distinguish between REST and not. I'm also not sure it is necessary, you can certainly have multiple class which provide REST and Web endpoints. You can even dynamically build routes within a route.
Hmm, this might be one of the few use cases for nested classes. But is would still require some routing trickery.
Feb 07 2018
prev sibling next sibling parent reply Seb <seb wilzba.ch> writes:
On Wednesday, 7 February 2018 at 17:04:13 UTC, Nicholas Wilson 
wrote:
 Is it possible to have some urls routed to serve content and 
 some to receive JSON in the same class? Basically I want:

 shared static this()
 {
     auto router = new URLRouter;
     auto a = new MyInterface;
     router.registerWebInterface(new MyInterface); //?? 
 selective combination
     router.registerRestInterface(new MyInterface); //??
     auto settings = new HTTPServerSettings;
     settings.port = 8080;
     settings.bindAddresses = ["::1","127.0.0.1"];
     listenHTTP(settings, router);
 }

 class MyInterface
 {
     SomeData[] items;
     // Get
     void index()
     {
         render!("index.dt");
     }
     // Get
     void getPage()
     {
         render!("page.dt", items);
     }

     // REST -> receive d as JSON.
     void postGiveMeData(SomeData d)
     {
         synchronized
         {
             items ~= d;
         }
     }
 }
How about using the normal Vibe.d Web Service? An example from my WIP project vibe-by-example project: https://github.com/wilzbach/vibe-d-by-example/blob/master/web/service.d I also have a fork of vibe.web.web that adds additional convenience features to Vibe.d: https://github.com/teamhackback/hb-web (I have been struggling to get most of them merged upstream - https://github.com/vibe-d/vibe.d/pulls/wilzbach)
Feb 07 2018
parent Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Wednesday, 7 February 2018 at 18:38:15 UTC, Seb wrote:
 How about using the normal Vibe.d Web Service?
Stupid question: whats the difference?
 An example from my WIP project vibe-by-example project:

 https://github.com/wilzbach/vibe-d-by-example/blob/master/web/service.d


 I also have a fork of vibe.web.web that adds additional 
 convenience features to Vibe.d:

 https://github.com/teamhackback/hb-web


 (I have been struggling to get most of them merged upstream - 
 https://github.com/vibe-d/vibe.d/pulls/wilzbach)
Feb 07 2018
prev sibling next sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 2/7/18 12:04 PM, Nicholas Wilson wrote:
 Is it possible to have some urls routed to serve content and some to 
 receive JSON in the same class? Basically I want:
 
 shared static this()
 {
      auto router = new URLRouter;
      auto a = new MyInterface;
      router.registerWebInterface(new MyInterface); //?? selective 
 combination
      router.registerRestInterface(new MyInterface); //??
      auto settings = new HTTPServerSettings;
      settings.port = 8080;
      settings.bindAddresses = ["::1","127.0.0.1"];
      listenHTTP(settings, router);
 }
 
 class MyInterface
 {
      SomeData[] items;
      // Get
      void index()
      {
          render!("index.dt");
      }
      // Get
      void getPage()
      {
          render!("page.dt", items);
      }
 
      // REST -> receive d as JSON.
      void postGiveMeData(SomeData d)
      {
          synchronized
          {
              items ~= d;
          }
      }
 }
Yes you can, but it's not pretty. interface MyInterface { void postGiveMeData(SomeData d); } class MyInterfaceImpl : MyInterface { void postGiveMeData(SomeData d) { ... } void getPage() { ... } void index() { ... } } auto myI = new MyInterfaceImpl; router.registerRestInterface(myI); router.get("/route/to/getPage", &myI.getPage); router.get("/route/to/index", &myI.index); This worked for me, but note that my "non-rest" function was static, so I didn't need to worry about instances. I'm not sure if the above works exactly right for you. However, I would recommend actually not doing this for your purpose. My case was different -- I still wanted routes that were REST routes, but I wanted to control the result streaming (the vibe.d return value doesn't work with ranges, so I would have had to construct essentially my entire database in an array so I could return it). In your case, I think you are better off using 2 classes, and one shared data storage area. -Steve
Feb 07 2018
parent Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Wednesday, 7 February 2018 at 18:47:05 UTC, Steven 
Schveighoffer wrote:
 Yes you can, but it's not pretty.

 interface MyInterface
 {
    void postGiveMeData(SomeData d);
 }

 class MyInterfaceImpl : MyInterface
 {
    void postGiveMeData(SomeData d) { ... }
    void getPage() { ... }
    void index() { ... }
 }

 auto myI = new MyInterfaceImpl;
 router.registerRestInterface(myI);
 router.get("/route/to/getPage", &myI.getPage);
 router.get("/route/to/index", &myI.index);

 This worked for me, but note that my "non-rest" function was 
 static, so I didn't need to worry about instances. I'm not sure 
 if the above works exactly right for you.

 However, I would recommend actually not doing this for your 
 purpose. My case was different -- I still wanted routes that 
 were REST routes, but I wanted to control the result streaming 
 (the vibe.d return value doesn't work with ranges, so I would 
 have had to construct essentially my entire database in an 
 array so I could return it).

 In your case, I think you are better off using 2 classes, and 
 one shared data storage area.

 -Steve
Thanks! (Some how I missed your post).
Feb 08 2018
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2018-02-07 18:04, Nicholas Wilson wrote:
 Is it possible to have some urls routed to serve content and some to
 receive JSON in the same class? Basically I want:

 shared static this()
 {
      auto router = new URLRouter;
      auto a = new MyInterface;
      router.registerWebInterface(new MyInterface); //?? selective
 combination
      router.registerRestInterface(new MyInterface); //??
      auto settings = new HTTPServerSettings;
      settings.port = 8080;
      settings.bindAddresses = ["::1","127.0.0.1"];
      listenHTTP(settings, router);
 }

 class MyInterface
 {
      SomeData[] items;
      // Get
      void index()
      {
          render!("index.dt");
      }
      // Get
      void getPage()
      {
          render!("page.dt", items);
      }

      // REST -> receive d as JSON.
      void postGiveMeData(SomeData d)
      {
          synchronized
          {
              items ~= d;
          }
      }
 }
Have you tried this? -- /Jacob Carlborg
Feb 07 2018
parent reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Wednesday, 7 February 2018 at 19:50:31 UTC, Jacob Carlborg 
wrote:
 Have you tried this?
No. But apart from the fact that I forgot to make the class inherit from an interface to that the rest interface would actually compile, the web interface is routed before the rest interface and so the rest interface would never be reached since the methods are all the same and the REST's are shadowed by the web's .
Feb 07 2018
parent reply Arjan <arjan ask.me.to> writes:
On Wednesday, 7 February 2018 at 20:23:10 UTC, Nicholas Wilson 
wrote:
 On Wednesday, 7 February 2018 at 19:50:31 UTC, Jacob Carlborg 
 wrote:
 Have you tried this?
No. But apart from the fact that I forgot to make the class inherit from an interface to that the rest interface would actually compile, the web interface is routed before the rest interface and so the rest interface would never be reached since the methods are all the same and the REST's are shadowed by the web's .
Makes me wonder whether or not vibe does honor the http request Accept headers? e.g.: application/json or application/javascript or text/html etc.
Feb 08 2018
parent Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Thursday, 8 February 2018 at 10:51:39 UTC, Arjan wrote:
 On Wednesday, 7 February 2018 at 20:23:10 UTC, Nicholas Wilson 
 wrote:
 On Wednesday, 7 February 2018 at 19:50:31 UTC, Jacob Carlborg 
 wrote:
 Have you tried this?
No. But apart from the fact that I forgot to make the class inherit from an interface to that the rest interface would actually compile, the web interface is routed before the rest interface and so the rest interface would never be reached since the methods are all the same and the REST's are shadowed by the web's .
Makes me wonder whether or not vibe does honor the http request Accept headers? e.g.: application/json or application/javascript or text/html etc.
Hmm, I hadn't considered the Accept Headers.
Feb 08 2018