I have a nameko service that deals with lots of entities, and having the entrypoints in a single service.py
module would render the module highly unreadable and harder to maintain.
So I've decided to split up the module in to multiple Services which are then used to extend the main service. I am kind of worried about dependency injection and thought a dependency like the db, might have multiple instances due to this approach. This is what I have so far:
the customer service module with all customer-related endpoints
# app/customer/service.py
class HTTPCustomerService:
"""HTTP endpoints for customer module"""
name = "http_customer_service"
db = None
context = None
dispatch = None
@http("GET,POST", "/customers")
def customer_listing(self, request):
session = self.db.get_session()
return CustomerListController.as_view(session, request)
@http("GET,PUT,DELETE", "/customers/<uuid:pk>")
def customer_detail(self, request, pk):
session = self.db.get_session()
return CustomerDetailController.as_view(session, request, pk)
and main service module that inherits from customer service, and possibly other abstract services
# app/service.py
class HTTPSalesService(HTTPCustomerService):
"""Nameko http service."""
name = "http_sales_service"
db = Database(Base)
context = ContextData()
dispatch = EventDispatcher()
and finally I run it with:
nameko run app.service
So this works well, but is the approach right? Especially with regards to dependency injection?
Yep, this approach works well.
Nameko doesn't introspect the service class until run-time, so it sees whatever standard Python class inheritance produces.
One thing to note is that your base class is not "abstract" -- if you point nameko run
at app/customer/service.py
it will attempt to run it. Related, if you put your "concrete" subclass in the same module, nameko run
will try to run both of them. You can mitigate this by specifying the service class, i.e. nameko run app.services:HTTPSalesService