-
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
docs: clean up WIP sections for sequence page #2994
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -217,30 +217,106 @@ namespace. | |
|
||
### Query string parameters | ||
|
||
{% include content/tbd.html %} | ||
OAI 3.0.x describes the data from a request’s header, query and path in an | ||
operation specification’s parameters property. In a Controller method, such an | ||
argument is typically decorated by @param(). We've made multiple shortcuts | ||
available to the `@param()` decorator in the form of | ||
`@param.<http_source>.<OAI_primitive_type>`. Using this notation, query string | ||
parameters can be described as `@param.query.string`. Here is an example of a | ||
controller method which retrieves a Note model instance by obtaining the `id` | ||
from the query string object. | ||
|
||
How to get query string param values. | ||
```ts | ||
@get('/notes/{id}', { | ||
responses: { | ||
'200': { | ||
description: 'Note model instance', | ||
content: {'application/json': {schema: {'x-ts-type': Note}}}, | ||
}, | ||
}, | ||
}) | ||
async findById(@param.query.string('id') id: string): Promise<Note> { | ||
return await this.noteRepository.findById(id); | ||
} | ||
``` | ||
|
||
You can also specify a parameter which is an object value encoded as a JSON | ||
string or in multiple nested keys. For a JSON string, a sample value would be | ||
`location={"lang": 23.414, "lat": -98.1515}`. For the same `location` object, it | ||
can also be represented as `location[lang]=23.414&location[lat]=-98.1515`. Here | ||
is the equivalent usage for `@param.query.object()` decorator. It takes in the | ||
name of the parameter and an optional schema or reference object for it. | ||
|
||
```ts | ||
@param.query.object('location', { | ||
type: 'object', | ||
properties: {lat: {type: 'number', format: 'float'}, long: {type: 'number', format: 'float'}}, | ||
}) | ||
``` | ||
|
||
The parameters are retrieved as the result of `parseParams` Sequence action. | ||
Please note that deeply nested properties are not officially supported by OAS | ||
yet and is tracked by | ||
[OAI/OpenAPI-Specification#1706](https://github.com/OAI/OpenAPI-Specification/issues/1706). | ||
Therefore, our REST API Explorer does not allow users to provide values for such | ||
parameters and unfortunately has no visible indication of that. This problem is | ||
tracked and discussed in | ||
[swagger-api/swagger-js#1385](https://github.com/swagger-api/swagger-js/issues/1385). | ||
|
||
b-admike marked this conversation as resolved.
Show resolved
Hide resolved
|
||
### Parsing Requests | ||
|
||
Parsing and validating arguments from the request url, headers, and body. See | ||
page [Parsing requests](Parsing-requests.md) | ||
page [Parsing requests](Parsing-requests.md). | ||
|
||
### Invoking controller methods | ||
|
||
{% include content/tbd.html %} | ||
|
||
- How to use `invoke()` in simple and advanced use cases. | ||
- Explain what happens when you call `invoke()` | ||
- Mention caching use case | ||
- Can I call invoke multiple times? | ||
The `invoke` sequence action simply takes the parsed request parameters from the | ||
`parseParams` action along with non-decorated arguments, calls the corresponding | ||
controller method or route handler method, and returns the value from it. The | ||
default implementation of | ||
[invoke](https://github.com/strongloop/loopback-next/blob/6bafa0774662991199090219913c3dc77ad5b149/packages/rest/src/providers/invoke-method.provider.ts) | ||
action calls the handler function for the route with the request specific | ||
context and the arguments for the function. It is important to note that | ||
controller methods use `invokeMethod` from `@loopback/context` and can be used | ||
with global and custom interceptors. See | ||
[Interceptor docs](Interceptors.md#use-invokemethod-to-apply-interceptors) for | ||
more details. The request flow for two route flavours is explained below. | ||
|
||
For controller methods: | ||
|
||
- A controller instance is instantiated from the context. As part of the | ||
instantiation, constructor and property dependencies are injected. The | ||
appropriate controller method is invoked via the chain of interceptors. | ||
- Arguments decorated with `@param` are resolved using data parsed from the | ||
request. Arguments decorated with `@inject` are resolved from the context. | ||
Arguments with no decorators are set to undefined, which is replaced by the | ||
argument default value if it's provided. | ||
|
||
For route handlers, the handler function is invoked via the chain of | ||
interceptors. The array of method arguments is constructed using OpenAPI spec | ||
provided at handler registration time (either via `.api()` for full schema or | ||
`.route()` for individual route registration). | ||
|
||
### Writing the response | ||
|
||
{% include content/tbd.html %} | ||
|
||
- Must call `sendResponse()` exactly once | ||
- Streams? | ||
The | ||
[send](https://github.com/strongloop/loopback-next/blob/6bafa0774662991199090219913c3dc77ad5b149/packages/rest/src/providers/send.provider.ts) | ||
sequence action is responsible for writing the result of the `invoke` action to | ||
the HTTP response object. The default sequence calls send with (transformed) | ||
data. Under the hood, send performs all steps required to send back the | ||
response, from content-negotiation to serialization of the response body. In | ||
Express, the handler is responsible for setting response status code, headers | ||
and writing the response body. In LoopBack, controller methods and route | ||
handlers return data describing the response and it's the responsibility of the | ||
Sequence to send that data back to the client. This design makes it easier to | ||
transform the response before it is sent. | ||
|
||
LoopBack 4 does not yet provide first-class support for streaming responses, see | ||
[Issue#2230](https://github.com/strongloop/loopback-next/issues/2230). As a | ||
short-term workaround, controller methods are allowed to send the response | ||
directly, effectively bypassing send action. The default implementation of send | ||
is prepared to handle this case | ||
[here](https://github.com/strongloop/loopback-next/blob/bf07ff959a1f90577849b61221b292d3127696d6/packages/rest/src/writer.ts#L22-L26). | ||
|
||
### Handling errors | ||
|
||
|
@@ -331,11 +407,12 @@ An example error message when the debug mode is enabled: | |
|
||
### Keeping your Sequences | ||
|
||
{% include content/tbd.html %} | ||
|
||
- Try and use existing actions | ||
- Implement your own version of built in actions | ||
- Publish reusable actions to npm | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. see #3021 for |
||
For most use cases, the | ||
[default](https://github.com/strongloop/loopback-next/blob/6bafa0774662991199090219913c3dc77ad5b149/packages/rest/src/sequence.ts) | ||
sequence supplied with LoopBack 4 applications is good enough for | ||
request-response handling pipeline. Check out | ||
[Custom Sequences](#custom-sequences) on how to extend it and implement custom | ||
actions. | ||
|
||
## Working with Express middleware | ||
|
||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A question: is it meant to be the string value get from the HTTP client?
If we are showing an example value from in the API explorer input field, probably wrap key&value with double quotes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I took this straight from API explorer and I think they're not wrapped because we define lat/long as number values.