Hacker News new | past | comments | ask | show | jobs | submit login

It'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



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: