-
Notifications
You must be signed in to change notification settings - Fork 386
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
Update LoopBack 4 docs with rest refactor changes #475
Changes from all commits
ec5e2bb
6b670fb
e84683a
f53143e
74a57ff
8968890
e0115f3
abab326
a467dc1
1d3b484
23b323a
cf39764
42bdfcc
28439b3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,9 @@ summary: | |
|
||
A `Route` is the mapping between your API specification and an Operation (JavaScript implementation). It tells LoopBack which function to `invoke()` given an HTTP request. | ||
|
||
The `Route` object and its associated types are provided as a part of the | ||
[(`@loopback/rest`)](https://github.com/strongloop/loopback-next/blob/master/packages/rest) package. | ||
|
||
## Operations | ||
|
||
Operations are JavaScript functions that accept Parameters. They can be implemented as plain JavaScript functions or as methods in [Controllers](Controllers.html). | ||
|
@@ -32,10 +35,11 @@ In the example above, `name` is a Parameter. Parameters are values, usually pars | |
- `header` | ||
- `path` (url) | ||
|
||
## Creating Routes | ||
## Creating REST Routes | ||
|
||
The example below defines a `Route` that will be matched for `GET /`. When the `Route` is matched, the `greet` Operation (above) will be called. It accepts an OpenAPI [OperationObject](https://github.com/OAI/OpenAPI-Specification/blob/0e51e2a1b2d668f434e44e5818a0cdad1be090b4/versions/2.0.md#operationObject) which is defined using `spec`. | ||
|
||
The route is then attached to a valid server context running underneath the | ||
application. | ||
```js | ||
const app = new Application(); | ||
|
||
|
@@ -48,17 +52,23 @@ const spec = { | |
} | ||
} | ||
}; | ||
const route = new Route('get', '/', spec, greet); | ||
app.route(route); | ||
|
||
app.start(); | ||
(async function start() { | ||
const server = await app.getServer(RestServer); | ||
const route = new Route('get', '/', spec, greet); | ||
server.route(route); | ||
await app.start(); | ||
})(); | ||
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. This will swallow any errors thrown from It makes me wonder, can we move methods like An mock-up: // inside RestComponent (or a mixin?)
app.rest = new RestServerConfigurator();
app.bind(RestBindings.CONFIGURATOR).toDynamicValue(() => app.rest);
// in RestServer constructor
class RestServer {
constructor(
@inject(RestBindings.CONFIGURATOR) configurator: RestServerConfigurator,
/*...*/) {
// define routes, handler, sequence etc. from the configurator
}
}
// usage in applications
app.rest.route('get', '/', spec, greet); This can be extended to support multiple rest servers by replacing Thoughts? 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. Let's leave this out of scope of this documentation update. |
||
|
||
``` | ||
|
||
## Declaring Routes with API specifications | ||
## Declaring REST Routes with API specifications | ||
|
||
Below is an example [Open API Specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#swagger-object) that defines the same operation as the example above. This a declarative approach to defining operations. The `x-operation` field in the example below references the handler JavaScript function for the API operation, and should not be confused with `x-operation-name`, which is a string for the Controller method name. | ||
|
||
```js | ||
|
||
const server = await app.getServer(RestServer); | ||
const spec = { | ||
basePath: '/', | ||
paths: { | ||
|
@@ -77,7 +87,7 @@ const spec = { | |
} | ||
}; | ||
|
||
app.api(spec); | ||
server.api(spec); | ||
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. This feels very wrong to me. The API is tightly coupled with Controllers and controllers are defined at application level. As a user, I'd expect Also, if the API is server-specific, and we have multiple REST servers configured, then each server can be providing a different REST API. Is it a good idea? 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.
My understanding was that we might have multiple controllers servicing more than one server, either of the same protocol or otherwise. Combine this with the idea that the OpenAPI spec handling is REST-specific and we end up with server-based API binding instead.
I think it's a great idea! Your microservice could have a public-facing API that defines its consumable endpoints, and a private/internal API for infrastructure, exporting logs, administration, or whatever you can think of. Without server-level API binding, these scenarios aren't possible anymore. Playing "Devil's Advocate" for a moment, if we want to strictly enforce the idea that a LoopBack application is a one-server microservice, then it would make sense to migrate some of this configuration back up to application level, and enforce the idea that you pick one, and only one server component to power the application. This would definitely make sense from a microservice architecture perspective, where you're minimizing the responsibility of each running instance and using other technologies to handle communication between services, log aggregation, etc. I think trying to simultaneously support both philosophies is easily doable, but could be a documentation and UX nightmare for new users. 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.
This is a pretty cool idea which makes a lot of sense to me 👍 I agree we should support this use case. My concern is about ease of use for people starting with the framework, notice how many of our examples increased in size. Anyways, this is out of scope of this pull request, because we have already updated may other places (package READMEs, example repos) to use the convention described in this pull request. To use a better convention, we will need to update both the docs and those other places. |
||
``` | ||
|
||
## Invoking operations using Routes | ||
|
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.
Can we revert this since either can be used as an example, but in the
Request-level context
section we expand onMySequence
?