8000 feat(express, koa): make transports similar by vonagam · Pull Request #2486 · feathersjs/feathers · GitHub
[go: up one dir, main page]

Skip to content

feat(express, koa): make transports similar#2486

Merged
daffl merged 1 commit intofeathersjs:dovefrom
vonagam:converge-express-koa
Jan 9, 2022
Merged

feat(express, koa): make transports similar#2486
daffl merged 1 commit intofeathersjs:dovefrom
vonagam:converge-express-koa

Conversation

@vonagam
Copy link
Member
@vonagam vonagam commented Nov 11, 2021

There are a few differences between express and koa servers. This PR tries to bring them closer.

There are some breaking changes for express (and koa, but since it appeared only in this version those do not matter much). Main ones:

  • Now positioning of .configure(rest()) matters and it should go after json() middleware (or others of such sorts).
  • middleware in ServiceOptions renamed to express (to differentiate from middleware for other transports).
  • authenticate middleware merges auth result into request.feathers (like it should) not request itself.

List of changes (in randomish order, excluding some small things):

  • Koa: rename source files to match files in express.
  • Express: fix missing usage of settings.strategies in parseAuthentication. (should be here, in koa it is used.)
  • Koa: add authenticate middleware, rename authentication to parseAuthentication.
  • Both: authenticate middleware now is a wrapper around authenticate hook, so behaves the same (before there were some inconsistencies).
  • Koa: add ability to add middleware for a service using options koa.before and koa.after.
  • Both: both store combined service middleware which include before, after, method call and a formatter in service options express.composed and koa.composed (can use unique symbol instead).
  • Core: options that are passed to service mixins are now the same that are stored on a service and available through getServiceOptions (before this line used an original unwrapped service and so was creating a copy).
  • Express: use routing from transport-commons (like koa and sockets).
  • Both: store routing lookup result on req/ctx (available for service middleware).
  • Koa: allow to pass preexisting koa app to constructor (just like express one allows).
  • Express: req.feathers does not contain headers by default, only provider.
  • Koa: rest() is a configure function now, not koa middleware, so should be used with .configure(), not .use(). A configure function is a more flexible approach (allows to add a mixin for example) and does not reveal implementation.
  • Koa: rest() adds parseAuthentication middleware just like express does right now.
  • Koa: rest() accepts formatter middleware that is a last step in service call processing, by default is an empty function, but it means that it does not call next(), so no falling through like right now (and consistent with express).

Aim is to remove differences in code as much as possible between those two transports, simplifying end-user migrations and easing porting features.


const protoService = wrapService(location, service, options);
const serviceOptions = getServiceOptions(service, options);
const serviceOptions = getServiceOptions(protoService);
Copy link
Member

Choose a reason for hiding this comment

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

Just a note for myself while I review: Since wrapService already calls getServiceOptions with the options, we don't need it here.

Copy link
Member
@daffl daffl left a comment

Choose a reason for hiding this comment

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

Alright, I wanted to take the time do a thorough review since this might have some backwards compatibility implications. Apologies it took so long, this is pretty awesome. My first concern was that the setup order that is required now would break existing generated applications but it looks like middleware is already set up in the correct order so this would just be something that needs to be mentioned in the migration guide.

My next question would be if this change would break any other expectations in existing applications. If routing is not done by Express, would things like app.use('*') and app.use('/existingservice', (req, res, next) => {}) still work?

Other than pointing out the order, is there anything else that needs to be updated in the documentation?

Oh also, I invited you to the organization, which should make it easier to collaborate on PRs 😄


if (authentication) {
debug('Parsed authentication from HTTP header', authentication);
req.feathers = { ...req.feathers, authentication };
Copy link
Member

Choose a reason for hiding this comment

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

💯 for removing Lodash!

@vonagam
Copy link
Member Author
vonagam 8000 commented Jan 5, 2022

Would app.use('*') work?

app.use('*', service), where service is a feathers service, would not work.
With feathers router one can use app.use('/:any', service) for the same thing.
Neither thing is tested though.

Would app.use('/existingservice', (req, res, next) => {}) work?

Yes, this is a tested feature and if something passed to use is not a feathers service then it is handled by an underlying framework.

But the order has been changed. Currently if you want to run this middleware before "existingservice" you need to put it before the service is registered, now instead you need to do it before rest middleware is added.

Is there anything else that needs to be updated in the documentation?

I listed breaking changes for express that I know of.
There might be others, but it means there were no tests for them to be noticed.

I invited you to the organization, which should make it easier to collaborate

I of course accept the badge of honor, but how does membership helps with collaboration?
Just in case - I'm on slack and always open to non-formal private conversations.

@vonagam vonagam force-pushed the converge-express-koa branch from 57075e0 to af6f70c Compare January 7, 2022 02:49
@daffl
Copy link
Member
daffl commented Jan 9, 2022

So after the discussion in Slack, I am going to merge this and see what happens 😄 we can always revert the routing or create a compatibiility wrapper but @vonagam was making a good point in the value of having the transports similar. Plus we can sell it as a performance improvement since our router is much faster than Express internal routing. Thanks again for doing this, some great improvements in there!

@daffl daffl merged commit 26aa937 into feathersjs:dove Jan 9, 2022
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.

3 participants

0