Skip to content
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

fix(rest): parse query string even when there is no rest query param #2089

Merged
merged 1 commit into from Dec 4, 2018

Conversation

raymondfeng
Copy link
Contributor

@raymondfeng raymondfeng commented Nov 28, 2018

See #2088

Now we use Express body parsers instead of body module. I think there was a side effect of body module that parses request.query beyond Express.

Checklist

  • npm test passes on your machine
  • New tests added or existing tests modified to cover all changes
  • Code conforms with the style guide
  • API Documentation in code was updated
  • Documentation in /docs/site was updated
  • Affected artifact templates in packages/cli were updated
  • Affected example projects in examples/* were updated

@bajtos
Copy link
Member

bajtos commented Nov 29, 2018

-1 from me, I have intentionally disabled query parsing when no query arguments are described in the operation spec.

@larsm11 @raymondfeng Let's discuss.

What is the use case for having query arguments not documented in the OpenAPI spec? I find the example provided in #2088 as too artificial. IMO, a real-world endpoint will want start and end query arguments described in the documentation so that API consumers are aware of them, client generators like swagger-codegen can include them in the client API, etc.

it('parses query without decorated rest query params', async () => {
// See https://github.com/strongloop/loopback-next/issues/2088
const server = await givenAServer({rest: {port: 0, host: '127.0.0.1'}});
server.handler(queryRequestHandler);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please inline the handler in this test case.

I find it difficult to understand what's going on in this test case when the query handler is defined elsewhere and the name does not explain what is the handler actually doing.

Alternatively, find a better name for this handler function, e.g. respondWithParsedQueryObject.

@raymondfeng
Copy link
Contributor Author

-1 from me, I have intentionally disabled query parsing when no query arguments are described in the operation spec.

I think disabling query parsing is over-restrictive. Parsing query string is not a heavy operation. There are valid use cases that we want to have query string parsed regardless of being referenced in a controller method argument.

  1. There are non-application specific query params, such as:
  1. We allow routes beyond ControllerRoute

@bajtos
Copy link
Member

bajtos commented Nov 30, 2018

There is also the question of consistency. So far, LB4 applications were usually parsing the query by calling qs with default arguments, see
https://github.com/strongloop/loopback-next/blob/8156f9d32aac3a0461b617a01cde9c319a1cceca/packages/rest/src/parser.ts#L122

With your change in place, this code will be effectively never called, because the query will be always parsed by the Express layer.

If we agree that the query should be parsed inside Express, then please clean up the code in packages/rest/src/parser.ts as part of that change. I think you will need to update few tests as well.

There are non-application specific query params, such as access_token, ...
We allow routes beyond ControllerRoute

Agreed.

My main objection is that all of these query parameters should be included in the OpenAPI spec for documentation purposes and for consumption by client generators.

Once these params are documented, we will automatically parse the query as part of argument processing.

On the other hand, I see that the current implementation does not work when the parsed query needs to be accessed before the parameter parser did it job, e.g. from a middleware or a custom sequence action called early in the sequence flow.

I guess that means we do need to change the behavior as you are proposing here.

@raymondfeng raymondfeng force-pushed the fix-2088 branch 2 times, most recently from 22ba32f to 7e6117b Compare November 30, 2018 16:42
@raymondfeng
Copy link
Contributor Author

If we agree that the query should be parsed inside Express, then please clean up the code in packages/rest/src/parser.ts as part of that change. I think you will need to update few tests as well.

I switch to express.query to parse query string for consistency.

@raymondfeng
Copy link
Contributor Author

@bajtos PTAL

packages/rest/src/parser.ts Outdated Show resolved Hide resolved
@raymondfeng
Copy link
Contributor Author

@bajtos Good feedback! PTAL.

Copy link
Member

@bajtos bajtos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, please consider addressing my comment below.

@@ -702,6 +688,8 @@ paths:
});

async function givenAServer(options?: {rest: RestServerConfig}) {
options = options || {rest: {port: 0}};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please note that givenHttpServerConfig sets the port to 0 by default. I think the following simpler version should work well too:

async function givenAServer(options: {rest?: RestServerConfig} = {}) {
   options.rest = givenHttpServerConfig(options.rest);
   // ...
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants