jester icon indicating copy to clipboard operation
jester copied to clipboard

[RFC] allow syntax sugar for automatically generating routes from procs as in D:vibe's registerWebInterface

Open timotheecour opened this issue 5 years ago • 4 comments

/cc @Araq @dom96

in D vibe, is D's analog to jester. Some ideas could be borrowed, one of them is a nice syntax sugar to avoid boilerplate in defining routes: see docs for registerWebInterface:

// snippet; see full example in http://vibed.org/api/vibe.web.web/registerWebInterface
class WebService {
// automatically mapped to: POST /login (all this is customizable, see docs)
//  input request is JSON that is automatically deserialized to this function's input
//  {"username": "bob", "password": "1234", "age" : 15. "scores" : [ 1.2, 3.4 ] }
// this functions' output  (here an associative array) is automatically serialized to JSON
auto postLogin(string username, string password, int age, double[] scores){
  return ["foo" : 21, "bar": 23];
}
// etc with other functions that map to other routes
}
void main(){
  new URLRouter.registerWebInterface(new WebService); // ...
}

in Nim/jester this could look like:

routesMagic:
  proc postLogin(username: string, password: string, age: int, scores: seq[float]): auto = {"foo" : 21, "bar": 23}.toTable
  proc getDateQuery(date: Datetime, id: string): auto = mongo.query(date = date, id = id)

registerWebInterface(routesMagic, serverSettings)

Likewise, registerWebInterface(myProc, myServer, myOptions = nil) can also be used to add a single route to a server

avoids boilerplate

currently we have to manually deserialize request.params, pass the deserialized arguments to a proc, call the proc, convert to json (for eg) and call resp

note

in D, all this is customizable (eg the post vs get, using a different path for a function name etc) via UDA (user defined attributes), but the defaults are often good enough and simple things map to really simple code that just looks like normal function (hiding serialization / deserialization except when necessary to to some customization)

in Nim, this can all be achieved as well (eg using jester specific pragmas), all it requires is compile time reflection

implementation

  • for each proc/template P in a scope (eg routesMagic), compute TInput = tuple of input argument types, Toutput = output type
  • then create a route eg if P.name=postLogin:
/"login":
  let tInput = request.params.deserializeJsonTo(TInput)
  let result = call proc P with tInput
  resp result.toJson()

timotheecour avatar Sep 04 '18 05:09 timotheecour

Sorry, but what exactly is proposed here? Is this a duplicate of https://github.com/dom96/jester/issues/134 ?

Araq avatar Sep 04 '18 06:09 Araq

unrelated (nothing to do with auth, despite the example using username, password); I'll try to explain better in a bit

timotheecour avatar Sep 04 '18 08:09 timotheecour

in D vibe, is D's analog to jester.

I don't think so. Jester is a lightweight web framework, vibe looks pretty heavy.

Your post isn't clear. Can you show valid Jester code that you think has too much boilerplate?

dom96 avatar Sep 04 '18 19:09 dom96

Here's an example adapted from my code:

# this is an existing API that takes regular Nim types and that we want to expose over the server
proc postExtractFilePattern(input: string, index:int, exactBounds: bool, action: Action) = ...

post "/extractFilePattern":
  resp extractFilePattern(request.params["input"], request.params["index"].parse(int), request.params["exactBounds"].parse(bool), request.params["action"])

which, under this proposal, could be simplified to:

# this is an existing API that takes regular Nim types and that we want to expose over the server
proc extractFilePattern(input: string, index:int, exactBounds: bool, action: Action) = ...

routes:
  post:
    extractFilePattern # will automatically do serialization/deserialization from function parameter input output types
    "myroutename", extractFilePattern # ditto, but with `"myroutename"` instead of `"extractFilePattern"`

timotheecour avatar Sep 10 '18 06:09 timotheecour