HTTP handlers calling RPC handlers-

55 views
Skip to first unread message

Patrick Lepore

unread,
Jul 26, 2017, 2:33:52 PM7/26/17
to nameko-dev
Hi, I'm working on a new project using Nameko and we're looking to have HTTP endpoints and well as RPC endpoints that return the same data.  Right now, I have a working setup where our HTTP handler that calls the RPC handler, formats the response and sends an HTTP response.  The RPC handler is what actually calls our dependencies.

This works fine using nameko run but is it recommended?  Also, for unit testing just the HTTP handler, is it possible to mock out the RPC dependencies using worker_factory so we don't need to initialize all of them with container_factory?  I found a related discussion on this mailing list here but I'm not sure if it applies.

Another thought I had was to add a helper method that calls our dependencies and then just have the HTTP handler and RPC handler call that.  Would this be preferred?  I imagine it would make testing easier since we could use restrict_entrypoints() to remove the RPC handler from HTTP unit tests and vice-versa for the RPC unit tests.

Thanks!

David Szotten

unread,
Jul 27, 2017, 4:38:59 AM7/27/17
to nameko-dev
Hi Patrick,

For your use-case, I'd probably recommend an option that's not very well documented (yet): you can stack entrypoint decorators

of course, this is slightly tricky with the current http and rpc decorators, since they have different method signatures, but this, in turn is easily fixed and will probably benefit a project like yours anyway:

See, the bundled http extension is built to be completely generic, but if you are hosting an api on top of nameko, you probably have conventions around parameters and return values. so, if you subclass the `HttpRequestHandler` and override `get_entrypoint_parameters`, `response_from_result` (and probably `response_from_exception` you can have an @my_http_api entrypoint decorator with the same signature as the @rpc decorator 

then your service can just be

class Service:
   
@my_http_api
   
@rpc
   
def my_method(self, param1, param2)
        do_stuff
()


for the entrypoint subclass, e.g. for `get_entrypoint_parameters`, instead of passing in the `request` object and parameters from your url, you might mandate the parameters be sent as a json document in the request body, and pull those values out and return as kwargs (similar to what the @rpc entrypoint does). 


Best,
David

Matt Yule-Bennett

unread,
Aug 22, 2017, 10:34:58 AM8/22/17
to nameko-dev
Sorry for the late reply here. Adding to what David has said -- 

The pattern you're using is fine, and in fact we use it as Student.com quite a lot. Entrypoints do not mutate the methods they decorate; when one method calls another, there's no difference between the target method being entrypoint-decorated or not.

The other approach of using a common helper that both kinds of entrypoints can call is also fine, but I would argue adds a level of redirection probably unnecessarily. The fact that RPC looks basically like a native python method means you may as well use it as the workhorse method.

For testing, the worker_factory doesn't involve extensions at all. It just gives you back an instance of the service method with (unless you specify alternatives) mocked out dependencies. The container_factory creates a container for whatever service class you give it, and restrict_entrypoints and replace_dependencies can be used to strip any extensions that you don't want before starting it. Unfortunately, as the other thread explains, they won't strip any subextensions. For services that use both AMQP and HTTP, that unfortunately means that you need to spin up the WSGI server and connect to Rabbit in order to start your container, even if you've stripped all the top-level extensions.

Patrick Lepore

unread,
Aug 24, 2017, 11:15:57 PM8/24/17
to Matt Yule-Bennett, nameko-dev
ok, thanks!

--
You received this message because you are subscribed to the Google Groups "nameko-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nameko-dev+unsubscribe@googlegroups.com.
To post to this group, send email to namek...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/nameko-dev/c130703b-856a-456a-8a82-50644029819c%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages