-
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
Configurable response types/formats #436
Comments
We probably should start to refactor https://github.com/strongloop/loopback-next/tree/master/packages/repository/src/types into its own package to form the LB.next typing system and leverage it for parameter parsing/conversion/serialization. |
Labelling as non-MVP, because we have a simple workaround available - users can use their own implementation of |
@dustinbarnes Take a look at the default implementation of Here is what you need to do:
|
@bajtos @dustinbarnes application.ts export class YourApp extends RepositoryMixin(Application) {
constructor() {
super();
// Assume your controller setup and other items are in here as well.
this.bind(RestBindings.SequenceActions.SEND).toProvider(CustomSendProvider);
} custom-send-provider.ts import { Send } from "@loopback/rest";
import { Provider, BoundValue } from "@loopback/context";
import { writeResultToResponse } from "@loopback/rest";
export class CustomSendProvider implements Provider<BoundValue>{
value(): Send | Promise<Send> {
return writeResultToResponse; // Replace this with your own implementation.
}
} If you're implementing multiple servers in your application, binding this key at the Application-level context will make that binding the default for all of the servers connected to it. This means that if you wanted different custom providers for different RestServer instances, you'd want to perform those bindings elsewhere (like in an async override of the In this example, PrivateSendProvider might allow stack traces to be returned via the response, whereas PublicSendProvider will not. in application.ts async start() {
const publicServer = await this.getServer('public');
const privateServer = await this.getServer('private');
publicServer.bind(RestBindings.SequenceActions.SEND).toProvider(PublicSendProvider);
privateServer.bind(RestBindings.SequenceActions.SEND).toProvider(PrivateSendProvider);
await super.start(); // Don't forget to call start!
} |
I created a follow-up issue to capture the instructions from Kevin in our docs - see #863. |
Does it fall under the "Validation and type conversion" epic #755 ? |
I don't think so. As I understand #755, it deals with input parameters. This story deals with outputs. I think the best epic to assign this story to is an epic for implementing a local in-process API Explorer and/or a capability to server static files. |
@bajtos Could we get an acceptance criteria for this issue? Thanks |
@bajtos ^^^ |
Hello. I am interested in having a JSONP response. I seem to believe this was available in LB3 out of the box. @bajtos when you refer to:
I assume you mean JSONP? If not, what would be the best way to achieve JSONP. There seems to be no way of differentiating the response based on the "Accept" header being sent. |
Not really. We want to allow the controller method to handle more aspects of the HTTP response that will be produced, e.g. status code, headers, etc. See #436 (comment) export class CustomerController {
@get('/:id', {responses: {...}})
async findById(id: string): RestResponse {
return {
statusCode: 200,
headers: {...};
content: {
'application/json': customer,
},
links: {...};
}
}
}
Our current recommendation is to write a custom implementation of sequence action
Yes, indeed - see https://github.com/strongloop/strong-remoting/blob/33fbd72fb46035f707c3c62dce6b36ab075fb61e/lib/http-context.js#L480-L483 I created a new issue to keep track of this feature - see #2752 |
What about this, I think it can work export class CustomerController {
@get('/:id', {responses: {...}})
async findById(id: string, @inject(Http.RESPONSE) response): Response {
return Object.assign(response, {
statusCode: 200,
headers: {...};
content: {
'application/json': customer,
}
links: {...};
})
}
} because writeResultToResponse bypass response if controller return the response |
This issue has been marked stale because it has not seen activity within six months. If you believe this to be in error, please contact one of the code owners, listed in the |
This issue has been closed due to continued inactivity. Thank you for your understanding. If you believe this to be in error, please contact one of the code owners, listed in the |
At the moment, the return value of a controller method/router handler is converted to the response using the following hard-coded algorithm:
response.write()
as-is and no content-type is set.We need a more flexible setup, we should at least honor "produces" configuration from the API specification.
Acceptance Criteria
A controller method should be able to specify
media type
for theresponses
object with@operation
. See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md#response-objectNote by @bajtos: I believe this is already supported, see e.g. the TodoController in our examples: https://github.com/strongloop/loopback-next/blob/cb308add60bbe938c8e85812676eb817e9e0efc9/examples/todo/src/controllers/todo.controller.ts#L32
A controller method should be able to return JS representation of the response body or a wrapper corresponding to the response objects. The goal: allow controller methods to control response status code and headers. E.g.
Location
for201 Created
responses to POST requests creating new model instances,Content-Type
andContent-Disposition
for file downloads.LoopBack should be able to match the response media types to the
Accept
request header to determine what content type to be produced for a given request. It will setContent-Type
response header.Have built in support for
application/json
andtext/plain
media-types.EDIT: Move to another task
The text was updated successfully, but these errors were encountered: