5 ms·
I agree. I particularly like Go's web ecosystem. A web server is just a function, and that function is often a composition of other functions (for example, a tr
by weberc2 9y ago
I agree. I particularly like Go's web ecosystem. A web server is just a function, and that function is often a composition of other functions (for example, a tree of router functions and then a handler for each route). By contrast, it seems like Flask goes to great lengths to obscure such a simple concept (decorators for routes, global variables for state and resource management, etc).
- icebraining 9y agoI wouldn't call it obscure, it's just an abstraction. But you can always use the underlying library (http://werkzeug.pocoo.org/ http://werkzeug.pocoo.org/), which does send everything through a function. Or just implement WSGI directly.
- weberc2 9y agoIt's not a very good abstraction, because (as previously mentioned) it depends on global variables to manage shared resources (e.g., connection pools) and even request state. Hence "obscure". It would be much cleaner to just define a handler type with the signature: `def handler(r: http.Request) -> http.Response`. Those handlers could be passed to routers (which themselves could be handlers), for example (not tested): class Route(typing.NamedTuple): path: typing.re.Pattern method: str handler: http.Handler class Router: def __init__(self, routes: typing.List[Route]) -> None: self.routes = routes def serve_http(self, r: http.Request) -> http.Response: """serve_http implements the http.Handler interface""" for route in self.routes: if route.path.matches(r.path): return route.handler(r) return http.NotFound("404 NOT FOUND") Note that since handlers are just functions, they can also be methods with object-level state. They needn't depend on global state at all, for example, notice how the following routes don't depend on the connection pool (or the request state) to be global: class Server(typing.NamedTuple): db: DBConnPool def first_route(self, r: http.Request) -> http.Response: """first_route uses shared `db` resource.""" pass def second_route(self, r: http.Request) -> http.Response: """second_route uses shared `db` resource too!""" pass