README
binding-resolution
This example application is created to demonstrate LoopBack 4's context binding resolution and dependency injection within a context hierarchy. The application is verbosely instrumented to print out context/binding information to help developers understand how bindings are resolved and injected based on the current context and the binding scope.
The application scenario
The context chain
When GET http://127.0.0.1/ping
is served, the following context hierarchy is
leveraged by various artifacts.
- Application
- RestServer
- RequestContext (for HTTP requests)
- InvocationContext (for interceptors)
- RequestContext (for HTTP requests)
- RestServer
Binding scopes for key artifacts
The artifacts below are bound to the context chain with certain scopes.
- Spy middleware (Singleton or transient)
- Spy interceptor (Singleton or transient)
- Ping controller (Transient or singleton)
- Logger service (Singleton)
- Request Logger service (Transient)
Binding resolution and injection
new BindingDemoApplication()
creates the application contextThe
RestApplication
registersRestComponent
to the application. As a result, theRestServer
is bound to the application context. TheRestServer
instance is the server context.app.boot()
discovers and loads the following bindings into the application context:- PingController
- SpyInterceptor
- LoggerService
- RequestLoggerService
app.middleware(SpyMiddlewareProvider)
bindsmiddleware.Spy
to the server context.When an HTTP request
http://localhost:/3000/ping
is sent, the rest server accepts the request, creates aRequestContext
and dispatches it to the middleware sequence.The
Spy
middleware is invoked. It createsLOGGER_SERVICE
in the request context as an alias toRequestLoggerService
.The
PingController.ping
is mapped for the route. A new instance ofPingController
is created within the request context. Its dependency ofLOGGER_SERVICE
is resolved and injected into the controller with an instance ofRequestLoggerService
.The
Spy
global interceptor is invoked and it has access to the invocation context.The
ping
method ofPingController
is invoked. Method parameter injection is performed to supply therequestCtx
parameter value.The
ping
method callsLogger
service.
Use
DEBUG=loopback:example:binding-resolution npm start
To force binding scope to be Transient
:
DEBUG=loopback:example:binding-resolution BINDING_SCOPE=transient npm start
Open http://localhost:3000/ping in your browser.
The console will print similar information as below:
loopback:example:binding-resolution [middleware.Spy*] Owner context: RestServer-v2IUN1iNSM6NCqpa6D8vWw-1 +0ms
loopback:example:binding-resolution [middleware.Spy*] Current context: RestServer-v2IUN1iNSM6NCqpa6D8vWw-1 +0ms
loopback:example:binding-resolution [middleware.Spy*] Request context: RequestContext-v2IUN1iNSM6NCqpa6D8vWw-3 +0ms
loopback:example:binding-resolution Request: GET /ping {...} +0ms
loopback:example:binding-resolution [services.RequestLoggerService] Owner context: BindingDemoApplication-v2IUN1iNSM6NCqpa6D8vWw-0 +9ms
loopback:example:binding-resolution [services.RequestLoggerService] Current context: RequestContext-v2IUN1iNSM6NCqpa6D8vWw-3 +0ms
loopback:example:binding-resolution <<services.RequestLoggerService>> (GET /ping) [controllers.PingController] Owner context: BindingDemoApplication-v2IUN1iNSM6NCqpa6D8vWw-0 +0ms
loopback:example:binding-resolution <<services.RequestLoggerService>> (GET /ping) [controllers.PingController] Current context: RequestContext-v2IUN1iNSM6NCqpa6D8vWw-3 +0ms
loopback:example:binding-resolution [globalInterceptors.Spy*] Owner context: BindingDemoApplication-v2IUN1iNSM6NCqpa6D8vWw-0 +1ms
loopback:example:binding-resolution [globalInterceptors.Spy*] Current context: BindingDemoApplication-v2IUN1iNSM6NCqpa6D8vWw-0 +0ms
loopback:example:binding-resolution [globalInterceptors.Spy*] Invocation context: InterceptedInvocationContext-v2IUN1iNSM6NCqpa6D8vWw-4 +0ms
loopback:example:binding-resolution <<services.RequestLoggerService>> (GET /ping) [controllers.PingController] Request context: RequestContext-v2IUN1iNSM6NCqpa6D8vWw-3 +1ms
loopback:example:binding-resolution <<services.RequestLoggerService>> (GET /ping) Response {...} +1ms
loopback:example:binding-resolution [middleware.Spy*] Request context: RequestContext-v2IUN1iNSM6NCqpa6D8vWw-5 +188ms
loopback:example:binding-resolution Request: GET /favicon.ico {...} +0ms
Contributions
Tests
Run npm test
from the root folder.
Contributors
See all contributors.
License
MIT