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

Question: How is the API of Spirit better than koa2? #13

Open
irisjae opened this issue Mar 18, 2017 · 3 comments
Open

Question: How is the API of Spirit better than koa2? #13

irisjae opened this issue Mar 18, 2017 · 3 comments

Comments

@irisjae
Copy link

irisjae commented Mar 18, 2017

I really appreciate the nice little project over here. But besides performance, isnt the API of spirit essentially similar to koa2? in spirit, middleware looks like
(handler) => (request) => handler(request)
which is similar, though more smooth, than koa2's
(ctx/* == request*/, next) => next()
I can't see advantages in the route definition, since if you're returning a response map, you're transmitting HTTP information too.
e.g. a route in spirit might be
route .define([ route .get ("/", [], () => { return "Hello World!" }) ])
whereas in koa2 i might do

var route = () => { return "Hello World!" };
app .use ((ctx, next) => { ctx .body = route (/*or whatever dependencies need be injected*/); return next (); })

I really enjoy the simple API of spirit, but I feel it might have made a bad distinction between routes and middleware; when routes have to return response maps, i feel that wouldve more elegantly been made as a middleware by default. Even more impure seems to be the dependency injection in the request; once again I feel like its the job of a middleware. If spirit aims to be pure, lets go all pure!

@FlorianWendelborn
Copy link
Contributor

I don't really like the middleware part, but for me personally the reason to use spirit is that it's predictable, easily testable and "without magic". I usually use the return {status, body, headers} variant of the API since IMO it's the most obvious way to respond to an HTTP request.

@hnry
Copy link
Collaborator

hnry commented Mar 23, 2017

@Irisjay Hey thanks for the questions, they are pretty popular ones I've seen.

But besides performance, isnt the API of spirit essentially similar to koa2 in spirit, middleware looks like...

They aren't (at least since I last looked at koa). They do seem similar, but the distinction is, you can't test the koa version as easily (though there's probably helper tools to make it easy).

From what I recall next() is just returning undefined. While in spirit calling handler(request) actually returns a value (promise of response). So if you're going to test it, it's literally just a javascript function.

// test a middleware
const request = { url: ..., method: "GET" } // <- requests are just simple objects, no need for a mock
const returned_value = middleware(request)
expect(returned_value).toBe(...)

Also instead of doing handler() which is similar to next() we actually pass the request along, so request isn't something that's hanging out of scope or being "injected" as a context in the case of koa. Basically the "next" handler is just a javascript function too that we call normally by passing arguments and grabbing it's return.

Really what middleware in spirit does is just wrap functions together to compose them. Similar to doing response = a(b(c(request))) where a, b, c are middlewares.

There is no magic in how spirit works compared to express, koa, hapi, etc. It's simply just a function calling another function passing along a input paramter (request) and returning a value (response)

I don't care about testing, or it doesn't seem more readable to me, so what else?

There's other practical benefits. Since the implementation is just javascript, nothing fancy, not huge object manipulating or object based routing...

  • It makes spirit's source small and simpler
  • It's simplicity is how it get it's performance
  • Since it's literally just functions and no real magic behind the scenes, you can do more outside what spirit does, and without risk of having to hack spirit for it to work.

For example making a "time travel" addon is possible (similar to redux / elm where you can see a request or response transform along every point to see what's going on).

Even more impure seems to be the dependency injection in the request; once again I feel like its the job of a middleware. If spirit aims to be pure, lets go all pure!

The dependency injection is just doing pattern matching

let {url, method} = request // cherry pick arguments from request
fn(url, method)            // call our function with the arguments

Middleware and route functions in spirit can seem similar because by design they were both meant to be just javascript functions.

Just a route function can be made more simple (through it's argument and return) and we can further strip away the idea of 'http' from them. And for it to really be just any other function.

The difference from this and koa, is this is by design in spirit, and in koa you have to wrap it to achieve this.

In spirit don't think of there being "routes" or a "route function", it's just a normal function you're defining how / when to be called.

when routes have to return response maps, i feel that wouldve more elegantly been made as a middleware by default

I don't think you should feel that way. I don't think of 'response maps' as a res object in express or koa, I think of it as just data being passed. Since it isn't tied directly to res or some context, you have a lot of options to refactor and keep things DRY depending on how you want it.

Hope it helps, sorry for it being long.

@FlorianWendelborn
Copy link
Contributor

FlorianWendelborn commented Mar 23, 2017

request isn't something that's hanging out of scope or being "injected" as a context in the case of koa — @hnry

This isn't true anymore, koa now just passes ctx to all functions.

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

No branches or pull requests

3 participants