A way to build a URL route


#1

From @asyncee on Wed May 02 2018 07:26:29 GMT+0000 (UTC)

Hello!

I have a service with eight http endpoints and i need to build urls for it with multiple different parameters. Are there any way to implement something like url_for in flask:

Example:

class Service:
    @http('GET', '/url-one/<token>')
    def handle_url_one(self, request, token):
        pass
    
    @rpc
    def get_url_one(self):
        return '/url-one/' + token   # This is not DRY and error-prone approach
        # Wanted: return self.url_for(self.handle_url_one, token)

Thanks!

Copied from original issue: https://github.com/nameko/nameko/issues/539


#2

From @mattbennett on Wed May 02 2018 12:38:33 GMT+0000 (UTC)

Nameko HTTP is built on Werkzeug, which is the WSGI library that underpins Flask. url_for is one of the conveniences that Flask adds, so it’s not available out of the box.

It’s not that hard to implement though. Nameko entrypoints attribute the service methods that they decorate, so you can inspect the service class to find them. This snippet should get you started:

from nameko.extensions import ENTRYPOINT_EXTENSIONS_ATTR
from nameko.web.handlers import http, HttpRequestHandler
from nameko.rpc import rpc


class Service:
    name = "serv"

    @http('GET', '/url-one/<token>')
    def handle_url_one(self, request, token):
        pass

    @rpc
    def get_url_one(self, token):

        entrypoints = getattr(self.handle_url_one, ENTRYPOINT_EXTENSIONS_ATTR)
        routes = [
            entrypoint.url for entrypoint in entrypoints
            if isinstance(entrypoint, HttpRequestHandler)
        ]
        return routes

Returns ['/url-one/<token>']. The logic you need to substitute the arguments into the string must exist in werkzeug somewhere.