outmoded / discuss

The "mailing list"
99 stars 9 forks source link

RealWorld example app implementation #482

Closed EricSimons closed 5 years ago

EricSimons commented 7 years ago

Hey Hapi folks — we've had requests to have a RealWorld backend implementation of Hapi (see https://github.com/gothinkster/realworld/issues/40)

@antony has said he's willing to build it, but if anyone else wants to help out and/or provide feedback to him that would be awesome 👍

antony commented 7 years ago

I've forked the repo and plan on making a start as soon as I've got some spare time.

Question for the community: Lab is the tool of choice for testing Hapi Apps. However compared to something like AvaJS or even Mocha is can look a bit clunky (insistence on 'done' etc). Is eschewing Lab in favour of something else against the RealWorld ethos?

Same question goes for using async/await. Hapi's internal code is purely callback based, but all the apps I build nowadays use async await, purely for clarity. Do I stick with Hapi's callback model, or shall I replicate what I use in the real world, for real applications?

AdriVanHoudt commented 7 years ago

The express example also uses callbacks so I would use that.

antony commented 7 years ago

@AdriVanHoudt It does, and then it uses promises for all the mongoose stuff. It's a bit of a mish-mash.

I might go with async await to provide the kind of clarity that sells me on HapiJS, unless there is some real strong opposition.

AdriVanHoudt commented 7 years ago

Well that is because of mongoose. But you are free to use async await ofc :O I actually have never seen hapi code with async await ^^ (beware of vague promise weirdness in the api though, https://github.com/hapijs/hapi/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20promise, but everything should work)

devinivy commented 7 years ago

You might be interested in using this helper if you want to write async handlers, whose errors are otherwise uncaught.

https://github.com/devinivy/toys/blob/master/API.md#toyshandlerasynchandler

AdriVanHoudt commented 7 years ago

+1 for better error handling but if the goal is to show of hapi I would personally go with the least amount of extra tooling plugins (callbacks). This makes it easier for newcomers to step in. For more advanced people, use all the toys you want ;)

viczam commented 7 years ago

why not go with jest?

antony commented 7 years ago

@AdriVanHoudt async/await is native in Node 7 - no extra tooling.

Agreed that whatever makes it better for newcomers should be used - but callbacks are probably the least readable style of development nowadays.

I'll have a think and see what makes for the most readable code.

antony commented 7 years ago

@viczam I've not really looked at jest recently, it was very new when I last looked - seems like it could be a good contender

sirgallifrey commented 7 years ago

+1 for making it happen! Every now and then someone asks for real life examples. It'll be very useful

I think @AdriVanHoudt has made a very good point! I think newcomers will not understand why there are a lot of helpers plugins if they don't feel the pain those helpers mitigate first.

@antony I agree with you that async/await is great for readability, but remember that hapi also supports node v6 which many people still use because of it's LTS active status.

Let me say again: I think it's super cool that you are doing this! I hope it works out!

P.S: If I'm not mistaken hapi also supports node v4 which has begun it's maintenance status, and I haven't seen any plan to drop support for it in favor of node v7 ~ v8, I Think this support will last at least until the end of it's maintenance status. But I'm not certain of this /\ it's just what I think :smile: correct-me if I'm wrong

antony commented 7 years ago

Compatibility is a very good point. I'll bear this in mind and for that reason alone probably not use async await.

I'm probably not going to try to support node v4 however - if we're trying to support newcomers, they'll likely start on > v6, and v4 will very shortly be obsolete.

nlf commented 7 years ago

IMO async/await should only be used if you're planning on doing it without a plugin, as in putting a big try/catch in every handler and ultimately calling reply yourself. What you're trying to highlight is how hapi is used in the real world, and I'm pretty sure the majority of folks still aren't using async/await.

I'd stick with callbacks or promises. Remember you can reply with a promise and hapi will resolve it for you and reply with the result and return an error if it throws. Much more idiomatic, and doesn't require a third party helper plugin.

As for testing, that's up to you. Lab is what hapi core projects use, but is by no means mandatory for consumers. I haven't personally tried using other test frameworks in some time but I do recall having some weird issues with mocha because of domains, but that was also back in the hapi 2.x days so I wouldn't be surprised if those are long resolved. Remember though that lab also supports promises by omitting the callback in each test and returning a promise instead.

There are a few situations where promises are handled a bit strangely, but I'm more than happy to help you sort out the best way to use them to make this example as nice as possible if that's the route you'd like to take.

But hey, like I said, that's just my opinion. It's your project :)

viczam commented 7 years ago

@antony Jest is as stable as it can get :) It has a very good documentation and requires almost no extra tooling to get the job done (as compared to mocha + chai + sinon + istanbul etc). Comes with prebuilt coverage (they use istanbul), improved jasmine matchers, great babel support, snapshot testing etc.. And yes, it's developed and maintained by facebook itself.

@nlf the try / catch constructs bring clarity to the code. You can Boom.wrap the errors if needed.

As a "real world" implementation I'd recommend a project I've been developing so far - https://github.com/makeen-project/makeen.

You have "built-in" support for latest and greatest js features (async / await, decorators etc). There's also an improved router that you can use to define routes in a more declarative way (example - https://github.com/makeen-project/makeen/blob/develop/packages/makeen-user/src/routers/Account.js). No magic behind, everything translates to hapi routes.

An alternative way to define plugins using - https://github.com/makeen-project/makeen/blob/develop/packages/makeen-core/src/libs/Plugin.js - again, it all translates to hapi's API, you just get some nice shortcuts.

There's so much more to it starting from the way I use lerna to create a monorepo and have the plugins be independent node packages, to the way I leverage https://github.com/viczam/octobus to define the business logic by leveraging a message driven architecture.

At the very least, you can have a look at the hapi plugins I'm integrating in a cohesive format.