-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to build models, repositories and controllers dynamically at runtime #4296
Comments
I came across the need to dynamically define controllers at runtime. const defineNewController = new Function(`return class TestController {
async create() {};
async get() { return 'Hello World'; };
}`);
const testControllerClass = defineNewController();
MetadataInspector.defineMetadata(
OAI3Keys.CONTROLLER_SPEC_KEY.key,
testControllerSpec,
testControllerClass,
);
app.controller(testControllerClass); Now is there a way to pass Request context (or request/response objects) to this controller? I need methods of this controller to be able to access request and response objects. |
Actually I was able inject Request and Response object into a dynamically created controller by also using const METHODS_KEY = MetadataAccessor.create<Injection, MethodDecorator>('inject:methods');
const injectionSpecs = getControllerInjectionSpecs(controllerClass);
MetadataInspector.defineMetadata<MetadataMap<Readonly<Injection>[]>>(
METHODS_KEY,
injectionSpecs,
controllerClass,
);
function getControllerInjectionSpecs(target: Object): MetadataMap<Readonly<Injection>[]> {
return {
'': [
{
target,
methodDescriptorOrParameterIndex: 0,
bindingSelector: RestBindings.Http.REQUEST,
metadata: {
decorator: '@inject'
}
},
{
target,
methodDescriptorOrParameterIndex: 1,
bindingSelector: RestBindings.Http.RESPONSE,
metadata: {
decorator: '@inject'
}
}
]
}
} |
For someone that doesn't want to Have a Some things to think about. |
Important: until #433 is implemented, controllers registered after app startup WILL NOT be picked up by our REST layer. I think we should include a note (a warning?) in the new documentation to explain the problem to readers. |
@raymondfeng , I'm assigning this to you since you'll be looking into it. Thanks. |
When can we expect this to be completed ? We have a project where this is required urgently. Is there a workaround right now ? Can someone please help ? |
@samarpanB AFAIK dynamic (un-)binding of controllers is already possible: #4296. I'm not too sure for models and repositories. |
@samarpanB, this task is part of our March milestone plan: #4767. @raymondfeng, any outlook on this? Thanks. |
@samarpanB We have already made good progress here: In master:
PR (optional) What's lagging is probably a documentation page or tutorial. |
Existing docs:
I think we can convert https://github.com/strongloop/loopback-next/blob/master/docs/site/Creating-CRUD-REST-apis.md into a regular page that glues the runtime/cli/example today to tell a story. |
Closing this issue as done. The documentation work will be covered in #2740. |
I am afraid this story was closed mistakenly. The stories and doc pages linked in #4296 (comment) (especially #2740) are relevant for the use case where the artifacts (models, REST APIs) are static, defined by source code files (models) and configuration files (model-api config files).
See also the Example section that's describing a very concrete use case that's not covered by existing documentation. I am re-opening this issue and assigning it to 2020Q2 + May milestone. |
@samarpanB I see how this feature can be useful to you. I believe all runtime bits are already in place, you can take a look at the demo application presented in #4235 to see how to use them in practice. Recently, I have opened an issue where to discuss multi-tenancy based on dynamic schema selection - I think that's your use case too? Please join the discussion in #5056. |
I was thinking about different ways how to document this feature and more importantly, how to make such documentation easier to find by our users. Here is an alternative approach to consider:
Thoughts? |
It would not be fun having to guess and search through the docs find out how to dynamically add models and controllers. However, I agree we should update those pages as well.
This is in theme with our current state of documentation, almost all the details are there but they are scattered around. Let's have a single page describing how to dynamically add models and controllers. A succinct doc with all the info on the same page causes minimal context switching and brings great joy to the reader 😃 |
Addressed in #5591. |
This is a follow-up for the spike #4235
So far, our documentation and tooling was focused on the use case where most of application artifacts are static, defined in source files. In the Epic From model definition to REST API #2036, we are working on a more declarative approach, where we have a model source file and a configuration file, and the bootstrapper creates the repository & controller classes during the boot process.
In this story, I would like to show our users even more flexible and dynamic approach, where they have full control of all aspects at runtime - from defining the model class (e.g. based on schema discovery) to exposing the REST API (or decide not to).
Examples
See the demo application presented in #4235:
Acceptance criteria
A new documentation page with the following sections & content:
MUST HAVE
ModelDefinition
object/products
forProduct
model).ModelDefinition
object from the discovered schema in juggler/LB3 format.The page can use code snippets from the demo controller (see #4235) to illustrate the approach in practice.
SHOULD HAVE
These items are not strictly required for the initial version. If you decide to leave them out, then create follow-up stories and/or move them to acceptance criteria of and existing story like #2740.
UserBase
provided by the app) instead ofModel
orEntity
.MyCustomRepository
provided by the app) instead ofDefaultCrudRepository
. We need to explain how to create a custom repository class (I think this part belongs to Repositories part of our docs?) and how to build a function for creating named repository classes from the repository class. For the second part, we can tell users to copy the code fromdefineCrudRepositoryClass
function. See also Docs for exposing REST API of a Model with no custom classes #2740.defineCrudRestController function
. See also Docs for exposing REST API of a Model with no custom classes #2740.The text was updated successfully, but these errors were encountered: