nirum-lang / nirum-python

The Nirum runtime library for Python
https://nirum.org/docs/target/python.html
MIT License
8 stars 9 forks source link

Inversed transport layer for Client #79

Closed dahlia closed 7 years ago

dahlia commented 7 years ago

Nirum compiler currently generates client classes of services by inheriting a service and Client at a time. Although the current design helps to generate less duplicated code and works well in ordinary cases, it's not good at adding or changing transport.

Suppose we have 2 services: customer-service and message-service. The current compiler generates 4 classes (2 interfaces and 2 client implementations) from the schema: CustomerService, CustomerServiceClient, MessageService, and MessageServiceClient. These two client classes assume we use the default HTTP transport. What if we need to use our own transport layer (say it's our own authentication protocol based on HTTPS) with these service clients?

One possible way is to subclass these client classes and override hooks like make_request(). Add a class named CustomerServiceClient2 and make it to inherit CustomerServiceClient with overridden make_request(). Also add MessageServiceClient2 and do the same thing. What if we need to add a more service? Add AnotherServiveClient2 and do the same thing. Repeat this when you add a new service.

It's basically because we use inheritance to extend transport. It can be more flexible if we refactor it to use composition instead of inheritance.

The following is how the currently generated code looks like:

class CustomerServiceClient(Client, CustomerService):
    ...

It should be changed to the following way:

class CustomerServiceClient(CustomerService):
    def __init__(self, transport: Transport) -> None:
        ...

In the above Transport is an interface type and we need to provide the built-in transport implementation like HttpTransport. When we use clients the code would look like the below:

client = CustomerServiceClient(transport=HttpTransport('https://api.example.com/'))

@admire93 Any opinions?

kanghyojun commented 7 years ago

Sound great! this design make it easy to support various transport like MQ as well. i'm trying to work this issue on this week.