Inversifyjs: Explicit controller binding with inversify-express-utils

Created on 18 Jan 2018  路  5Comments  路  Source: inversify/InversifyJS

Hi there and thanks for your amazing work on InversifyJS!

I've recently started using the inversify-express-utils and am looking for a clean way of registering the controllers on the container without having to rely on it being a side effect of using the @controller decorator.

I see that the inversify-restify-utils allows that, so is there a similar mechanism for the express version?

Thanks,
Jan

Most helpful comment

@remojansen any updates on the auto-generation of OpenApi specification feature?

All 5 comments

Hi @jan-molak sorry but due to some changes in the last few versions, it is not possible now.

We use the @controller to create some metadata. Then when the server is created we read the metadata to find all the controllers in the application and declare all the routes.

You can check how @controller works:

https://github.com/inversify/inversify-express-utils/blob/master/src/decorators.ts#L8-L40

This change is part of a bigger plan:

  • We are working on a module that will be able to auto-generate the OpenApi specification but it is not ready yet.

  • We are working on a framework that will provide an API with a much higher level of abstraction https://github.com/ZafiroJS/

If you don't want to use a decorator you can try to use it as a function.

controller(path, middleware)(SomeClass);

But that is probably not what you need?

Thanks for the prompt reply, @remojansen! Yes, I've gone through the @controller code already and noticed that it's also retrieving the controllers bound to the container, so I was hoping that binding could be done explicitly.

Using @controller as a function is a lovely idea, thanks for that :) I think I could do that as part of my container module definition to keep it clean:

export const context = new ContainerModule((bind: interfaces.Bind) => {
    bind<SomeMicroService>(Types.SomeMicroservice).to(SomeMicroservice);

    controller('/api/some-service', ...someMiddleware)(SomeRestAdapterForMyMicroservice);
});

This way the controller is only registered when the ContainerModule is loaded. Granted, as a side effect, but I can live with that until ZafiroJS is ready.

Thanks for your help!

Jan

Hi!

Are you still working on the auto-generation of OpenApi specification feature?

@jan-molak Your solution is outstanding for another reason too:

I can easily define paths without using magic strings! That is not easy or neat to do within a decorator.

@remojansen This approach is so good it should be added to the docs as an alternative. The benefits as I see them are:

  • registration is explicit: it doesn't occur as a side effect, and so is predictable and maintainable and testable
  • eliminates magic strings in paths (can be kept in one place, e.g. a config class)

EDIT:
That eliminates magic string on the controller, but the action methods still have magic strings... :disappointed:

@remojansen any updates on the auto-generation of OpenApi specification feature?

Was this page helpful?
0 / 5 - 0 ratings