-
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
Spike: How to write a LB3-like LB4 application in JavaScript #1978
Comments
Suggestion to make this a bit more concrete: add a |
I agree, I would not mind helping out on this one |
Created a POC - https://github.com/strongloop/loopback4-example-javascript. |
Branch stage-f is the latest optimization in an attempt to create a JavaScript API for LB4. Findings
Notes
Suggestions
|
Some notes from the spike meeting. It was decided that we focus on usecase scenarios instead of 100% porting LB4 API to JS. Plain JS for SOME parts for the app:
Technical implementations to figure out:
|
Just a quick summary of a chat I had with @hacksparrow on Slack. My expectations were not matching the goal of this spike as written in the issue description.
I thought that we are looking for a way how to expose most of LB4 features to JavaScript developers. After reading the description, I see that the scope of this spike is much smaller. As I understand that scope, we are looking for a solution to support developers upgrading from JavaScript Express-based application to LB4, one that will allows them to write their Express-style routes in LB4 style and get the benefit of OpenAPI-driven request validation & API docs. A small incremental step on their journey from Express handlers to LB4 controllers (eventually). An important requirement that's not mentioned in the spike description, but that applies to all our spikes for JavaScript support: I would LoopBack users to write idiomatic ES6 code. They should use To make sure the spike is covering enough complexity of real-world applications, I am proposing to use the following scenario to drive the work: As a developer using JavaScript to write LB4 application, I want to create a route that will
I want to setup the route in such way that LoopBack will validate the value provided by the caller for the |
Here are few approaches to research: (1) Access the implementation of individual sequence actions directly by calling const parseParams = require('@loopback/rest').parseParams; (2) IIRC, if you don't provide any constructor, then your class will inherit the constructor from you base class. I think class MySequence extends DefaultSequence {
handler: async function (context) {
try {
const { request, response } = context;
const route = this.findRoute(request);
const args = await this.parseParams(request, route);
const result = await this.invoke(route, args);
this.send(response, result);
} catch (err) {
this.reject(context, err);
}
}
} (3) Use Service locator pattern to resolve dependencies. Service locator is an older pattern that is considered as an anti-pattern in modern object-oriented design, but it may serve us well until we find a JavaScript solution for Dependency Injection. class MySequence {
handler: async function (context) {
const route = await context.get(RestBindings.SequenceActions.FIND_ROUTE);
const parseParams = await context.get(RestBindings.SequenceActions.PARSE_PARAMS);
// etc.
try {
const {request, response} = context;
const route = findRoute(request);
const args = await parseParams(request, route);
const result = await invoke(route, args);
send(response, result);
} catch (err) {
reject(context, err);
}
}
} |
@nabdelgadir @dhmlau do you remember why was the goal of this spike changed from Express-like to LB3-like applications? I am puzzled about why would we want developers to build LB3-like applications with LB4? It makes sense to me to build Express-like applications, but why LB3-like? |
@bajtos thanks a lot for adding more clarity. |
@bajtos pasting this from Slack:
When I asked if we are looking to implement 100% support for LB4 APIs in JavaScript, you replied:
With that context, can you elaborate on what you are referring to as "request metadata"? As mentioned by you:
This one's just for capturing information for the subsequent spike. |
What's been done WRT the goals in the description: Find out the following, focus on what can be done right now without changing the code too much a. How to create and boot application class in javascript: Identify pain points We should probably close this story now, because its scope and goals are ambiguous and confusing; and we have identified more clearer follow up spike and tasks. |
@strongloop/loopback-next thoughts? |
IIUC, the goal for this spike is to find out:
It was under the assumptions/hypothesis (to be verified in the spike) that:
Therefore, it seems to me that the spike is complete (without the need to dive into the advanced features). To be honest, I forgot why we've changed from |
I love this part, that's how I would like to write LB4 apps in pure JavaScript 👍 I'll review the rest later this week. Sorry for the delays. |
As I see it, @hacksparrow has researched two different approaches for supporting JS in LB4. We have certainly learned more about the problem domain 👍 My problem with the current status is that neither proposal offers a solution with a great user experience, I'd like us to try harder to find an approach that JavaScript developers will love to use. Also let me remind us that a spike is considered as done when there are follow-up stories created and the acceptance criteria for these stories are clear enough & approved by the team or at least the leads. If we close this spike as done, then we are in a similar position as before this spike started - we don't know how JS support should look like and don't have any clear path to get there either. I agree that this spike story has pretty uncertain description and it's not clear what is in and out of scope. I like the idea of creating more focused & better defined follow-up spike stories to continue with our research. So before we call this spike done, I'd like @hacksparrow to:
|
Sure. By request metadata I am referring to data bound to per-request context, typically current request/response objects and more importantly metadata contributed by extensions like `@loopback/authentication (e.g. the currently logged-in user). |
@bajtos @raymondfeng @strongloop/loopback-next here is the proposal for the followup tasks. Anything needs to be clarified or you'd like to be added, do let me know. 1. Spike: Dependency injection or its alternative in JSLB4 Acceptance criteria: a. Should be demonstrated in a class 2. Spike: Create Route in JSLB4 Acceptance criteria: a. Should be created as a class 3. Spike: Create Sequence in JSLB4 Acceptance criteria: a. Should be created as a class 4. Spike: Create Model in JSLB4 Acceptance criteria: a. Should be created as a class 5. Spike: Create Repository in JSLB4 Acceptance criteria: a. Should be created as a class 6. Spike: Create Controller in JSLB4 Acceptance criteria: a. Should be created as a class I think, once Spike 1 is sorted out, everything else will come along smoothly. |
@hacksparrow, thanks for breaking the tasks down. Which one(s) you think we should get it done by Q1? It's part of the release planning/pruning we did yesterday. |
@dhmlau for a practical LB4 JS API, all of them. |
@bajtos @raymondfeng, probably need your inputs here as well. Had a discussion with @hacksparrow today. Here are my questions/thoughts:
What do you think? |
Good questions, @dhmlau. The 6 spikes above are addressing different technical aspects (road blocks) that are preventing LB4 users from writing their applications in JavaScript. They don't necessarily lead to an MVP solution - some of them may be beyond the scope of MVP, we may discover more missing pieces when we start putting together a cohesive MVP story. I see the following challenge this research: we need to work both at high-level design to find a solution that's easy to use and attractive to JS developers, and at the same time keep in mind low-level technical limitations imposed by JS. At high-level, we already have several tools and multiple different ways for designing the applications. Some of them may work better in JS, some will not work at all. Few examples of different high-level approaches we haven't looked at yet: To define the REST API, one can use design-first approach where the API is described in Dependency management can be implemented via Service Locator pattern. I am personally not fan of this approach, it makes it too easy to create highly-coupled code that's difficult to test in isolation, but if it makes JavaScript code easier to write & read compared to DI alternatives, then it's probably a trade-off we should accept. What I am trying to say here is that we haven't explorer all options already offered by the current LB4 code base, not to mention new options that will require only minimal improvements. From MVP perspective, I am proposing to use our If it makes things simpler, I am fine with leaving out customization of the Sequence. AFAICT, the Todo example app is working well will the built-in default sequence. Now the question I am not able to answer without further research: considering developer experience but also implementation effort required in our runtime, what is a better approach for building the Todo example app: use handler-based routes via Take
A comment on a side: I have an idea for an API allowing route handlers to receive dependencies via DI. It's not a solution for DI in general, but may work well for this particular case. app.route(
'get',
'/todos',
['repositories.TodoRepository'], // a list of dependencies
spec, // describe filter arg & return values
async function findTodos(TodoRepository, filter) {
// ^^^ dependencies first, spec parameters second
return TodoRepository.find(filter);
}); Because the number of arguments is growing out of hand a bit, a new object-style may work better: app.route(
verb: 'get',
path: '/todos',
inject: ['repositories.TodoRepository'], // a list of dependencies
spec, // describe filter arg & return values
handler: async function findTodos(TodoRepository, filter) {
// ^^^ dependencies first, spec parameters second
return TodoRepository.find(filter);
},
}); |
@hacksparrow please copy this proposal into a markdown file and commit it into a git. I find it difficult to discuss changes in content that's posted as a comment only. |
Links to the follow up tasks for this spike:
@bajtos can we close this spike now? |
Please create a spike or a story to create a JavaScript version of our Todo example application (minus GeoCoder API), as described in my earlier comment. I think we also need a follow-up task to modify our I also posted few comments in the follow-up issues you created, please consider to include the information from those comment in issue descriptions/acceptance criteria.
Other than that, I am fine with closing this issue as done. |
Added spike for Todo example application- #2501. |
Added issue for supporting the JS app scaffolding in |
@bajtos good to close this now? |
Description / Steps to reproduce / Feature proposal
In the spike,
Connect to #560
Out of Scope
See Reporting Issues for more tips on writing good issues
The text was updated successfully, but these errors were encountered: