Skip to content
This repository has been archived by the owner on Apr 8, 2019. It is now read-only.

New Lessons and Solutions #259

Closed
zoe-1 opened this issue May 12, 2018 · 2 comments
Closed

New Lessons and Solutions #259

zoe-1 opened this issue May 12, 2018 · 2 comments

Comments

@zoe-1
Copy link
Contributor

zoe-1 commented May 12, 2018

New assignment preparations below.

[Assignment1] Let's get started!

First, we need some basic structure: a lib folder, a package.json file, and an initial ./lib/index.js.
Since we will be using hapi, we need to include that in the project dependencies.
Second, create a basic hapi server on port 8000 which responds to /version requests and replies with a simple { "version": "0.0.1" } JSON payload. The version data in the response should come from the package.json file.

Original Assignment1

Assignment1 solution

[Assignment2] Plugins

The right way to work with hapi is to build your application using plugins.
Plugins provide a way to organize your code into logical components and then put them together in
different combinations or deploy them in different configurations. While some plugins are published as general purpose utilities (e.g. adding authentication),
you should think of plugins as a way to break your code into pieces.

Now that we have a basic server with one endpoint, we want to move the creation of the endpoint to a plugin,
and then register that plugin with the server. Creating a new file lib/version.js and move the /version endpoint there,
wrapped in the plugin register() function.

Then change our current lib/index.js to require the new file and register the version plugin with our server.

Remember to follow the style guide, and ask any questions in the comments of the
issue created for the assignment. If you are not sure how to get your fork back in sync with the current updated code, use the
git guide.

Helps

  • require('./version') should be declared at the top and assigned to Version`.
  • no need to wrap the plugin in { register: Version }. It is enough to just pass Version directly to the register() function.
  • no need for specifying the plugin version in the attributes. This is an internal plugin, not a publicly published one.

source for Helps: Discussion between @hueniverse and @thealphanerd.
Original Assignment2

Assignment2 Solution

[Assignment3] Testing & 100% coverage

  • [] cleanup server options validation

Things are getting a bit more interesting...

It's time to add tests, verify coverage, confirm style, and automate all of this with CI.
We will be using the lab module to perform all these tasks and automate it with travis.

  1. Add a .travis.yml file. When a .travis.yml file exists in a GitHub repository the project is built and all tests are executed. .travis reports if all tests successfully passed or not.
  2. Add a test folder with two files, version.js and index.js, each testing the corresponding file under /lib.
  3. Modify the package.json file to include the tests, as well as the dev dependency to lab.
  4. When using lab, enable coverage, require 100% coverage, enable linting with default rules, and use the code assertion library.
  5. Write a basic test to verify our version endpoint in version.js.
  6. Export init() and move the invocation to a new start.js file (which will call the exported init() function with the 8000 port and a callback outputs the information to the console when started).
    Change package.json file to use the start.js file as the starting place. start.js file is not be covered by tests.
  7. Write a test to get 100% coverage.

Everything should be pretty straight forward. If you are not sure on how to use lab and code,
look at other hapi.js modules and copy their test scripts and setup.

Getting 100% coverage can be tricky sometimes so if you are not sure, get as much coverage as you can, and comment on the lines in your pull request where you are having a hard time reaching and someone will give you a clue.

Remember to properly stop() your servers when calling the init() method in each test.

For now, avoid using any of the before() and after() lab features.

As always, ask for help and help others!

Helps

  • When stubbing / patching code in a test, mark that test with the { parallel: false } lab option to make it both safe for future parallel testing as well as visual cue.
  • Never return anything other than an actual Error as an error (e.g. no strings, plain objects, etc.).
  • Never use fixed port numbers in tests, only 0 or the default.
  • Always return before next() unless there is a reason to continue.
  • Make arguments / options in init() required.
  • When calling server.inject() with a GET request, just pass the path string as the first argument instead of an options object. Makes the code much more readable.
  • Use the testing shortcuts boilerplate used in hapi. Makes reading tests easier.

Original assignment3
Assignment3 Solution

[Assignment4] Authentication

  • add hapi-auth-bearer-token
  • auth strategy is registered in it's own plugin './authtoken.js'
  • all routes must have valid token to be accessed
    • currently only one route exists: /version.
    • valid token equals 12345678
  • 100% tests coverage. Adjust tests for token auth.

Original Assignment4
Assignment4 Solution

[Assignment5] TLS

  • tls the project.

Assignment5 Solution

[Assignment6] /authenticate & /private end points

  • build ./authenticate and ./private points.
  • use prerequisite extensions to execute authentication logic.
  • Make simple database.js data store to authenticate user records with.
  • Apply default authStrategy to ./private point.
  • No authStrategy for ./authenticate point.
  • Add { debug: false } config for tests.
    Otherwise, the tests print out hapi-auth-bearer-token error reports.
    Originally, added in assignment9 but can go here.

Assignment6 Solution

[Assignment7] catabox-redis

  • generate bearer-token upon successful authentication (cryptiles).
  • Set bearer-token in catbox-cache along with user record.
  • Expire the token after xxxxx time. Set expiresIn: value with server.options.
  • configure scopes ['admin', 'member'] for role based access.
  • create ./private point which requires admin scope for access.
  • pre-empt one user from generating multiple tokens.

Assignment7 Solution

[Assignment8] confidence

  • Build confidence object in ./lib/configs.js
  • Configure the object to be filtered by the env criteria
  • (environment).
    The environments will be production, test, default.
    • production: configurations for deployment.
    • test: configs for testing.
    • default: configs for running on local enviroment.
  • docs: https://github.com/hapijs/confidence
  • TLS and confidence:
    • confidence manipulates the tls certs if they are
      loaded in the Confidence object. To solve the issue
      load tls certs into configs object after confidence
      generates it.

Assignment8 Solution

[Assignment9] good & lifecycle

good hapi process monitoring & extending hapi request lifecycle

  • [] update to good v8.1.1
    built this lesson using good@8.0.0-rc1 before stable 8.1.1 released.
    npm i good@8.0.0-rc1
  • configure good console to write log reports to a logfile.
    Configure confidence file for good to log: test, production, and default.
  • Catch invalid attempts to access the ./private route.
    Extend the onPreResponse step of the lifecycle for the ./private route.
    When invalid tokens are used to access ./private, log the event to logfile.
  • Add { debug: false } config to Confidence file for tests.
    Otherwise, the tests print out hapi-auth-bearer-token error reports.

Assignment9 Solution

[Assignment10] refactor

-[] determine if this is proper place to refactor.
Or, rewrite previous assignments so no refactor is needed.

plugins

  • make a user plugin.
  • move user logic (./authenticate) from version plugin and place
    in user.
    routeMethod cleanup
  • make routeMethod directory. Move route methods out of the route plugin.
  • place routeMethods in routeMethod directory files.
    Ex) methods used in the ./authenticate route will be stored in
    routeMethod/authenticate.js file.
  • The goal is to make plugin route objects extremely readable.

tree after do refactor

lib/
├── authtoken.js
├── cache.js
├── certs
│   ├── cert.crt
│   └── key.key
├── config.js
├── database.js
├── index.js
├── routeMethod
│   ├── authenticate.js
│   ├── private.js
│   └── version.js
├── start.js
├── user.js
└── version.js

Assignment10 Solution

[Assignment11] hapi & graphql (part1)

Assignment11 Solution

[Assignment12] hapi & graphql (part2)

Basic graph schema, queries and data source

  • small data source of several hapi repositories
    • query accesses plugin data which can return:
      • id
      • name
      • description
      • related [Array of related repositories]
    • test coverage
    • linting ignores graph files.

Assignment12 Solution

[Assignment13] hapi & graphql (part3)

  • schema interfaces and types:
    • one interface: Repositories
    • three types: Hapi, xHapi, Topics.
    • 'xHapi' repositories are repos not under the hapi umbrella.
    • graphql searches / queries:
      • simple searches based on repositories id.
      • retrieve related repositories
      • retrieve related repositories of related repositories
        (friend of friends)
      • inlineFragraments retrieve topics if repo is xHapi type.
      • inlineFragraments retrieve topics of related projects if is
        xHapi type.
    • Changed data store to be an array of records / objects.
      • preparing for mutations.

Assignment13 Solution

[Assignment14] hapi & graphql (part4)

  • flow added project
    - https://flow.org
    - facebook's static type checker
    - lib/graphi/src files are:
    * checked by flow
    * compiled by babel
    * Note: flow only checks schema related files.
    Not to be used on hapi server files.

    • Build simple plugins to load graphql schemas and resolvers.
      • pass server object to modules so server.app.db can be
        accessed by resolver functions.
    • removed old schema logic

Assignment14 Solution

[Assignment15] hapi & graphql (part5)

  • mutation queries
  • handle requests to update repository name.
  • resolver to make update to data store.
  • tests 100%

Assignment15 Solution

[Assignment16] refactor

  • Think about how to implement refactored code earlier so the refactor is not needed.
  • consider using rethinkdb right from the start. However, this would add
    a new level of complexity on top of learning about hapi and graphql.
  • Does adding graphql to the project distract from learning hapi?
    Based upon talk I hear about graphql thought adding it to the project may attract more people.

university-rewrite

@devinivy
Copy link

This is awesome! Are you looking for feedback, or is it feeling ready to you?

@zoe-1
Copy link
Contributor Author

zoe-1 commented Nov 21, 2018

@devinivy Thanks for the input.
I want to get this project back up to speed.
But, lately been busy with a dive into cryptography.

No excuses
run cleanup
hapi extends

@zoe-1 zoe-1 closed this as completed Nov 22, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants