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

superagent vs. node-fetch #53

Closed
kaievns opened this issue Apr 19, 2016 · 9 comments
Closed

superagent vs. node-fetch #53

kaievns opened this issue Apr 19, 2016 · 9 comments

Comments

@kaievns
Copy link
Contributor

kaievns commented Apr 19, 2016

Another thing regarding testing. I've noticed that you use node-fetch for hitting your API in tests. Which is great but not nearly as safe and performant as mounting an app in the same process and hitting it through an internal socket as superagent does.

Also, not to brag, but i've built a thing called doubleagent which is kind of like superagent but is Promise based through and through and specifically tuned for testing JSON APIs (meaning it does JSON data serialization/deserialization and so on)

and it also decouples the JSON APIs testing from the assertion libraries. so, unlike superagent you can use it with whatevers and feel good about your day

@davidbanham
Copy link
Contributor

The thing I like about fetch over superagent is that it doesn't tie you to the express/connect ecosystem. You could scaffold out a suite of specs for a redbeard-api-compliant server, then go off and build that server in Elixir or Go if you wanted.

In the light of day, though, that's probably not that big of a deal. It's simple enough to switch superagent back to fetch if you decide you want to do a thing like that.

and it also decouples the JSON APIs testing from the assertion libraries. so, unlike superagent you can use it with whatevers and feel good about your day

Nice! Superagent getting involved in assertion always made me feel icky.

I'd be happy to switch from fetch to doubleagent. I'd be a little reticent to switch to raw superagent, though, given the assertion weirdness.

@nwinch
Copy link
Contributor

nwinch commented May 4, 2016

I don't like superagent due to it's "kinda promise not really promise" nature - perhaps it's more up to spec these days? If node-fetch is being used purely for testing (and not elsewhere in the app), and there is something such as doubleagent that will automatically handle the minutiae of dealing with JSON requests/respones, then I'm all for it.

But if we need an ajax lib for multiple purposes, then I think node-fetch would be a more appropriate choice.

I like fetchs Response object as it does deserialize JSON data with .json(), and offers you some other useful functions if you need them - though node-fetch only supports .text() and .json() - but you still need to serialize the data manually prior to that. Though we could easily create a helper function for that in testing - and while we're at it clean up the constant (res => res.json()) with a similar helper.

@s-taylor
Copy link
Contributor

s-taylor commented May 4, 2016

One issue I think i'm about to run into with node-fetch is it doesn't encode query strings for you. You can use another library of course, but most request libraries normally do this for you.

@nwinch
Copy link
Contributor

nwinch commented May 4, 2016

Hmm kinda sucks you gotta do that yourself :/

@s-taylor
Copy link
Contributor

s-taylor commented May 4, 2016

Or at least it's not documented if it does it for you... Why don't we use Axios like we have before?

@nwinch
Copy link
Contributor

nwinch commented May 4, 2016

I'm happy with axios for an all round option, for app and testing usage. One question here is are we only talking about this lib for testing? Or is it needed elsewhere in the app?

@s-taylor
Copy link
Contributor

s-taylor commented May 4, 2016

It's just for testing in redbeard

@kaievns
Copy link
Contributor Author

kaievns commented May 4, 2016

ok, a few points.

  1. i think the argument that fetch is good because you can write a spec in javascript and then implement it Elixir or Go is a bit far stretched. I mean, you could, but why would you? Both Elixir and Go have exceptionally good testing utilities. So, chances that you will end up in this situation are close to zero in my opinion.
  2. afaik, doubleagent is not bound to express/connect world. it is bound to the standard http. and that is a good thing, because it can connect a lot of wires automatically for you. Again, probability that you will use something that is not express/connect/http compatible is next to zero. And if you will, just don't use the doubleagent. Problem solved.
  3. fetch is build for the client-side usage. it's a good alternative to XMLHttpRequest when you just need to, well "fetch" a thing, but it is a pain in the neck to work with a full fledged JSON API. Think of fetch as a standardized jQuery.ajax, it's okay, but it is a bit simplistic and naive. Something like axios will be a better option practically every time.
  4. axios is okay, but doubleagent will do more for you, for example sockets wiring and automatic JSON data serialization both ways. this might sound like a small difference but it is a tricky problem actually. for example you boot your server manually and bind it to a specific port. That is not the most efficient solution and it is prone to port conflicts. doubleagent connects to your server via an in-memory socket, which is faster and collision free. Small things like that.

I guess the real question you need to ask yourself here is whether you'd prefer to have more boilerplate or more magic? that is the whole difference in mindsets here I think. i don't like code generators much. i believe that if a problem is so repetitive that it can be generated over and over again, it should be abstracted.

you like fetch and axios because they're simple straightforward tools and you can replicate the result by using a code generator. i prefer a good abstraction that will handle all the edge cases for me consistently, so i didn't have to type things in myself or use a code generator to type it for me.

i believe that every line of code in a code base (written manually or otherwise) is a maintenance overhead. and that is why i tend to fold everything into abstractions like doubleagent. this way if i screw up, i can patch it in one place.

@davidbanham
Copy link
Contributor

i think the argument that fetch is good because you can write a spec in javascript and then implement it Elixir or Go is a bit far stretched. I mean, you could, but why would you? Both Elixir and Go have exceptionally good testing utilities. So, chances that you will end up in this situation are close to zero in my opinion.

Yep, agreed. It's not a big deal.

afaik, doubleagent is not bound to express/connect world. it is bound to the standard http. and that is a good thing, because it can connect a lot of wires automatically for you. Again, probability that you will use something that is not express/connect/http compatible is next to zero. And if you will, just don't use the doubleagent. Problem solved.

ORLY? That's brilliant. Superagent docs all talk about how it's for express/connect apps so I assumed it was using some of the magic they layer on top of http. I'm happy to roll with doubleagent regardless, since the fact that it doesn't get all up in your assertions means it's pretty simple to swap out anyway. If it's not bound, though, that's icing on the cake.

fetch is build for the client-side usage. it's a good alternative to XMLHttpRequest when you just need to, well "fetch" a thing, but it is a pain in the neck to work with a full fledged JSON API. Think of fetch as a standardized jQuery.ajax, it's okay, but it is a bit simplistic and naive. Something like axios will be a better option practically every time.

I dreamed a dream where http on the client and server were both exactly the same. Figured it would be a nice reality which is why I started playing with fetch. If people are finding the .json() and query params stuff a burden, though, I'm happy to ditch it. It is a pretty low level API.

axios is okay, but doubleagent will do more for you, for example sockets wiring and automatic JSON data serialization both ways. this might sound like a small difference but it is a tricky problem actually. for example you boot your server manually and bind it to a specific port. That is not the most efficient solution and it is prone to port conflicts. doubleagent connects to your server via an in-memory socket, which is faster and collision free. Small things like that.

Agree doubleagent is a better fit for tests. Application code can use axios, fetch or whatever else depending on needs.

I guess the real question you need to ask yourself here is whether you'd prefer to have more boilerplate or more magic? that is the whole difference in mindsets here I think. i don't like code generators much. i believe that if a problem is so repetitive that it can be generated over and over again, it should be abstracted.

I tend towards minimal magic, but maximal modularity for code reuse. I think we're aligned there.

i believe that every line of code in a code base (written manually or otherwise) is a maintenance overhead. and that is why i tend to fold everything into abstractions like doubleagent. this way if i screw up, i can patch it in one place.

Absolutely agree there. Every line is something you must carry with you forever. I think what this points out, though, is that we need to sync on "Why is this thing a generator and not a library?". We've got what we think are real good reasons for that, but it would be good to get your input.

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

No branches or pull requests

4 participants