Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/nfroidure/whook

Build strong and efficient REST web services.
https://github.com/nfroidure/whook

dependency-injection hacktoberfest openapi openapi3 rest-api router server

Last synced: 4 days ago
JSON representation

Build strong and efficient REST web services.

Awesome Lists containing this project

README

        

[//]: # ( )
[//]: # (This file is automatically generated by a `metapak`)
[//]: # (module. Do not change it except between the)
[//]: # (`content:start/end` flags, your changes would)
[//]: # (be overridden.)
[//]: # ( )
# whook
> Build strong and efficient REST web services.

[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/nfroidure/whook/blob/main/LICENSE)

[//]: # (::contents:start)

Why write code when you have an OpenAPI 3.1 definition?

![The Whook's logo](./whook.svg)

## Summary

Whook eats your documentation and provides you with a performant router that
takes care of running the right code for the right operation.

By using the [OpenAPI](https://www.openapis.org/) standard and the dependency
injection pattern, Whook provides a convenient, highly modular and easily
testable back end framework.

## Quickstart

To start a new Whook project:

```sh
# Initialize the project
npm init @whook;
cd my_project_name;

# Check install with a dry run of the server
npm run dev -- __inject httpServer,process,dryRun

# Run tests
npm t

# Start developing
npm run watch

# Build the project
npm run build

# Start the compiled project
npm start

# Start the built project
node builds/local/server/start.js

# Create a new handler/service/provider
npm run whook -- create
```

## Why use Whook?

- robust: types, functional programming
- highly modular, extendable and reusable
- fully integrated and production ready
- can be deployed anywhere (serverless, docker, microservices): enter the
anylith era
- easy to test: TDD, E2E tests made easy
- feature complete for most API use cases
- ease your work but embrace projects complexity

## Usage

A tutorial is still to be written, expect it to come very soon. The above
[quickstart command](#quickstart) is a good starting point.

That said you can check the following "How to" PRs:

- [add GraphQL](https://github.com/nfroidure/whook/pull/62)
- [deploy with Docker](https://github.com/nfroidure/whook/pull/164)
- [deploy on AWS Lambda](https://github.com/nfroidure/whook/pull/54)
- [deploy with GCP Cloud Functions](https://github.com/nfroidure/whook/pull/66)

Also, the [`packages/` folder](./packages) contains a lot of easy to setup
modules with well detailed readmes and setup instructions.

Finally, search for Whook's package easily with the
[NPM's Whook tag](https://www.npmjs.com/search?q=keywords:whook). Also the
[Knifecycle tag](https://www.npmjs.com/search?q=keywords:knifecycle) can be
useful to find projects using the same dependency injection framework.

If you have any question or issue using Whook, post your help request to stack
overflow with the
[Whook tag](https://stackoverflow.com/questions/ask?tags=whook). Questions with
this tag will be regularly checked by Whook's authors.

Finally, if you encounter any bug (unexpected error, feature requests, OpenAPI
specification violation), please fill an issue!

## Principles

[Check this deck](https://slides.com/nfroidure/introducing-whook) for a complete
introduction to Whook's principles!

### Global overview

This projects aims to make creating well documented and highly customizable REST
APIs a breeze. It is the final outcome of my experience
[building REST APIs with NodeJS](https://insertafter.com/en/blog/http_rest_apis_with_nodejs.html).

By relying on the [OpenAPI schemas](https://www.openapis.org/) to declare a new
endpoint, this project forces documentation before code. It also is highly
customizable since based on the dependency injection with inversion of control
pattern allowing you to override or wrap its main constituents.

![Architecture Overview](./overview.svg)

The Whook route handling flow is very simple.

First, we have a HTTPServer that handles requests and serves responses (the
`httpServer` service).

Then, the `httpTransaction` transform the NodeJS requests into raw serializable
ones (raw objects with no methods nor internal states, useful for testing).

Then the router (`httpRouter`) deal with that request to test which handler
needs to be run by comparing the method/path couple with the OpenAPI operations
declarations.

Once found, it simply runs the right handler with the OpenAPI parameters value
filled from the serializable request. The handler simply have to return a
serializable response object in turn.

If any error occurs within this process, than the `errorHandler` is responsible
for providing the now lacking response object based on the error it catches.

And that's it, you have your REST API. We have
[no middleware](http://insertafter.com/en/blog/no_more_middlewares.html) concept
here. Instead, every handler is a simple function taking paramters and returning
a response. It makes those functions very easily composable (in a functional
programming sense).

You may add global wrappers to change every handlers input/output on the fly or
add a local wrapper specifically to one of a few handlers.

### Core concepts

Whook work by adding ingredients to you API:

- **configuration**: Whook look ups for `config/{NODE_ENV}/config.js` files. It
creates constants you can inject in your handlers and services.
- **API**: It defines the various endpoint of your API and how to map these to
handlers thanks to the well known OpenAPI format (formerly Swagger),
- **handlers**: the code that implement the API endpoints,
- **services**: various services that deal with side effects,
- **wrappers**: higher order functions you can apply to handlers (CORS,
authentication...).

You can see a lot of those concepts implemented in the
[Whook example](./packages/whook-example) folder.

Whook's DI system relies on the
[Knifecyle](https://github.com/nfroidure/knifecycle) module. It is great for
adding or easily override/wrap a lot of its core component and brings
instrumentation and testability to your code bases.

## Contributing

Contributors are very welcome to help pushing Whook forward!

Clone this project's repository and run:

```sh
npm i
npm run build
npm run metapak
npm t
```

The repository is based on LernaJS that allows to host several NPM packages in a
single repository. That said, to keep it simple it only proxies the packages
commands.

Install those
[VSCode extensions](https://insertafter.com/en/blog/my_vscode_configuration.html)
to get a smooth developer experience.

For committing run:

```sh
npm run cz
```

## Publishing

```sh
NODE_ENV=cli npm run lerna -- publish
```

[//]: # (::contents:end)

# Authors
- [Nicolas Froidure](http://insertafter.com/en/index.html)
- [Vincent Da Silva](https://dasilvavincent.github.io/PortFolio/)
- [Ayoub HAD-DAD](https://github.com/AubHaddad)

# License
[MIT](https://github.com/nfroidure/whook/blob/main/LICENSE)