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

refactor(rest): use Express req/res types #1326

Merged
merged 2 commits into from
May 17, 2018

Conversation

bajtos
Copy link
Member

@bajtos bajtos commented May 15, 2018

Redesign the REST layer to internally assume than Express has already processed and enhanced the request and response objects.

The public API for creating a listening HTTP server remains unchanged for now, i.e. our RestServer can be still used directly with the core http/https Server classes.

This pull request is a follow-up for #1082 and a part of #1253, it also fixes #191.

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 bajtos added refactor REST Issues related to @loopback/rest package and REST transport in general labels May 15, 2018
@bajtos bajtos added this to the May Milestone milestone May 15, 2018
@bajtos bajtos self-assigned this May 15, 2018
@@ -14,14 +14,14 @@ import {AuthenticationBindings} from '../keys';
* Passport monkey-patches Node.js' IncomingMessage prototype
* and adds extra methods like "login" and "isAuthenticated"
*/
export type PassportRequest = ParsedRequest & Express.Request;
export type PassportRequest = Request & Express.Request;
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we still have to keep & Express.Request?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch, I'll refactor and clean up the authentication module as part of this PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually, Express.Request is not the Request object from express js! Instead, it's a passport interface describing additional API added by passport middleware to the request object.

Copy link
Contributor

@raymondfeng raymondfeng left a comment

Choose a reason for hiding this comment

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

Please fix CI failures.

@raymondfeng
Copy link
Contributor

Please rebase to latest master to pick up a fix that passes the CI.

@bajtos bajtos force-pushed the feature/leverage-express-server branch from 6b31cc5 to 7099c99 Compare May 16, 2018 11:39
@bajtos
Copy link
Member Author

bajtos commented May 16, 2018

  • Rebased on top of the latest master.
  • Reviewed all places using Request, Response, ServerRequest and ServerResponse and fixed as necessary. See 1bf73d4, I'll squash this commit before merging.
  • Performed additional cleanup in authentication extension, see 7099c99

@raymondfeng
Copy link
Contributor

Please fix the lint error before merging:

ERROR: /home/travis/build/strongloop/loopback-next/packages/rest/src/sequence.ts[11, 3]: 'Request' is declared but its value is never read.
ERROR: /home/travis/build/strongloop/loopback-next/packages/rest/test/acceptance/sequence/sequence.acceptance.ts[7, 3]: 'Request' is declared but its value is never read.

Copy link
Contributor

@virkt25 virkt25 left a comment

Choose a reason for hiding this comment

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

@@ -4,7 +4,7 @@
// License text available at https://opensource.org/licenses/MIT

import {Strategy, AuthenticateOptions} from 'passport';
import {PassportRequest} from '../../..';
import {Request} from 'express';
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this be imported from @loopback/rest?

Copy link
Member Author

Choose a reason for hiding this comment

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

Here is my reasoning: MockStrategy is extending from Passport Strategy, which uses Request from express.

If we ever change @loopback/rest to export Request as a different type, then MockStrategy still needs to keep using Request from express, because that's what the Strategy interface requires.

import {RestBindings} from './keys';
import {RequestContext} from '.';
import {RequestContext} from './request-context';
import * as express from 'express';

export type HttpRequestListener = (
req: ServerRequest,
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be Request not ServerRequest?

Copy link
Member Author

Choose a reason for hiding this comment

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

No. HttpRequestListener is passed to http.createServer, it must work with core ServerRequest/ServerResponse (no Express additions).

@@ -8,6 +8,8 @@
* https://github.com/hapijs/shot
*/

// tslint:disable:no-any

import {ServerRequest, ServerResponse} from 'http';
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this be Request / Response from express now?

Copy link
Member Author

Choose a reason for hiding this comment

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

There are two ways how to use these Shot helpers:

  1. To test LB4 code like a Sequence action. To do that, we need to mock Express Request/Response objects.

  2. To test LB4 RestServer's request handler in isolation, without calling http.createServer. In this case, we need to mock core HTTP ServerRequest/ServerResponse objects.

That's why I am importing both Express and core HTTP types.

@bajtos
Copy link
Member Author

bajtos commented May 17, 2018

@virkt25 regarding _redirectToSwaggerUI - good catch! I'll also leverage res.redirect API provided by Express to further simplify that method 👍

Redesign the REST layer to internally assume than Express has
already processed and enhanced the request and response objects.

The public API for creating a listening HTTP server remains unchanged
for now, i.e. our RestServer can be still used directly with the core
http/https Server classes.
Now that the REST layer uses Express request/response types internally,
we can simplify StrategyAdapter by removing ShimRequest.

While making these changes, other places are cleaned up as well.
@bajtos bajtos force-pushed the feature/leverage-express-server branch from c271b25 to 8925db8 Compare May 17, 2018 06:38
@bajtos bajtos merged commit f864688 into master May 17, 2018
@bajtos bajtos deleted the feature/leverage-express-server branch May 17, 2018 07:12
@bajtos
Copy link
Member Author

bajtos commented May 17, 2018

Landed. I'll address any additional comments in a follow-up pull request if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
refactor REST Issues related to @loopback/rest package and REST transport in general
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Spike: Use express constructs / enable express shimming for Authentication
3 participants