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

Facade for tink_web #108

Open
back2dos opened this issue Apr 21, 2020 · 5 comments
Open

Facade for tink_web #108

back2dos opened this issue Apr 21, 2020 · 5 comments

Comments

@back2dos
Copy link
Member

To facilitate usage of tink_web (especially for newcomers), I propose putting a facade in tink.Web:

package tink;

class Web {
  static macro function serve(root:Expr, ?options:Expr);
  static macro function connect(target:Expr, ?options:Expr);
  static macro function test(root:Expr, ?options:Expr);
}

Serving via serve

The simplest usage should be this:

tink.Web.serve(root)

The recommended usage for when api and implementation are separate will be (new RootImpl() : RootApi).

With all the bells and whistles:

tink.Web.serve(
  root,
  {
    container: someContainer | someString,
    middlewares: [],
    getSession: someFunction,
    renderError: someFunction,
    exposeApi: true | false,
  }
);

Each of the optional fields explained:

  • container:
    • nothing: a container is automatically determined (if possible) with host/port taken from Sys.args()
    • a string: a container is automatically determined (if possible) with host/port taken from environment, e.g. for "PET_STORE" port will be Sys.getEnv("PET_STORE_PORT")
    • a container: the container is used for serving
  • middlewares: an array of HTTP middlewares that will all be applied to the routing handler
  • getSession: if provided, routing uses an authed context,
  • renderError: will be used instead of OutgoingResponse.reportError
  • exposeApi (for later): will make the signatures of the router available on / if some magic header is set ... we may also wish to make this the default.

Remoting via connect

The simplest usage:

tink.Web.connect(('http://full.url/goes/here':RootApi));
// if the server uses exposeApi, one may also use
tink.Web.connect('http://full.url/goes/here');

All options:

tink.Web.connect(
  ('http://full.url/goes/here':RootApi),
  {
    headers: [],
    augment: ({}: tink.http.Client.Pipeline),
    client: someClient,
  }
);

Testing via test

For creating a LocalContainerClient (and the whole container and handler it is connected to):

tink.Web.test(
  root,
  {
    middlewares: [], // not sure this makes sense
    getSession: someFunction,
    renderError: someFunction,
  }
);
@back2dos
Copy link
Member Author

Added bonus: if -main class has no main method, serve it.

@grepsuzette
Copy link
Contributor

How often do people need to create a new web server in a given year?

If not often, my opinion is seeing the plumbery for beginners in the main() function is rather a good thing. It trains familiarization with higher level plumbery rather than intimidating the user with porcelaine.

In coconut we have nice porcelaine already and it’s awesome. But for tink_web? Think porcelaine routes are enough :)

@benmerckx
Copy link
Member

Plumbing and familiarizing should happen after a successful GET / => hello world though :)
If this proposal reduces getting started to this I think it's a good thing.

class Main {
  @:get('/')
  public function hello()
     return 'hello world';
  static function main()
    tink.Web.serve(new Main());
}

Or with #108 (comment)

class Main {
  @:get('/')
  public function hello()
     return 'hello world';
}

@grepsuzette
Copy link
Contributor

grepsuzette commented Apr 22, 2020

It is not difficult at all to obtain a “hello world” with current tink_web. The selling point is strong already.

Also when I see this short exemple i think it is weird to have a webserver running without specifying the port and more importantly the binding ip (think with NodeContainer it listens to all interfaces by default so like 0.0.0.0 and ipv6 too, but something like 127.0.0.1 would be a more sensible choice as it would make it unavailable from the LAN, especially if we combine that with an exposeApi and a beginner that may just expose stuffs this way, and who 1 month afterwards may not even have begun to realize that, potentially leaking stuffs in a cafe or whereever).

If we go with the idea I think at least there should be a message when launching a server “Listening on :” and “Exposing Api thru ”. But nobody likes messages printed by a layer underneath and neither do I :) So changing to 127.0.0.1 by default and exposeApi:false maybe would be saner.

But in the end I still don’t see who needs this facade API.

@kevinresol
Copy link
Member

Generally speaking, I also don't find this super useful or does it help tink_web gain more popularity. Especially when we need to consider the effort to build and maintain it. I would prefer putting the effort in something else.

exposeApi could be useful, but only if it can consume some open standards. Otherwise the interfaces would be available in Haxe sources anyway, and can be used with Remote already.
(who wants to write client against an API written in tink_web, but doesn't have the Haxe source?)

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

4 participants