Skip to content

Commit

Permalink
Edit/Create - Documentation refactor (#46)
Browse files Browse the repository at this point in the history
doc: improved documentation
  • Loading branch information
riccardozambito committed Jul 28, 2020
1 parent 522a6c5 commit 7d1f12a
Show file tree
Hide file tree
Showing 8 changed files with 520 additions and 74 deletions.
169 changes: 95 additions & 74 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div align="center">

# Custom Plugin Node Library
# Mia service Node.js Library

[![Build Status][travis-svg]][travis-org]
[![javascript style guide][standard-mia-svg]][standard-mia]
Expand All @@ -10,30 +10,91 @@

</div>

**The Mia-Platform Plugin Node Library**

This library is intented to ease the creation of new services to deploy
This library is intended to ease the [creation of new services](https://docs.mia-platform.eu/development_suite/api-console/api-design/services/) to deploy
on [Mia-Platform][mia-platform].
Is highly copled with [`lc39`][lc39] and on [Fastify][fastify].
Built on [`Fastify`][fastify], it takes advantage of Mia-Platform Node.js service launcher [`lc39`][lc39].

# Getting Started
You can use this module in your projects or, from the [DevOps Console](https://docs.mia-platform.eu/development_suite/overview-dev-suite/), get started quickly and easily with a [ready-to-use microservice template](https://docs.mia-platform.eu/development_suite/api-console/api-design/custom_microservice_get_started/). Even in the [Mia-Platform Marketplace](https://github.com/mia-platform-marketplace) repository, you can find some examples and templates that using this library.

## Getting Started
## Setup the local development environment

### Install
To develop the service locally you need:
- Node.js v12 or later.

To install the package you can run:
To setup node.js, we suggest using [nvm][nvm], so you can manage multiple versions easily.
Once you have installed nvm, you can go inside the directory of the project and simply run
`nvm install`, the `.nvmrc` file will install and select the correct version
if you don’t already have it.

Once you have all the dependency in place, you can launch:
```shell
npm i
npm run coverage
```

These two commands, will install the dependencies and run the tests with the coverage report that you can view as an HTML
page in `coverage/lcov-report/index.html`.

## Install module

To install the package with npm:

```sh
npm install @mia-platform/custom-plugin-lib --save
npm i @mia-platform/custom-plugin-lib --save
```
To install with Yarn:

```sh
yarn add @mia-platform/custom-plugin-lib
```
## Define a Custom Service

You can define a new Custom Service that integrates with the platform simply writing this:
```js
const customService = require('@mia-platform/custom-plugin-lib')()

module.exports = customService(async function helloWorldService(service) {
service.addRawCustomPlugin('GET', '/hello', function handler(request, reply) {
request.log.trace('requested myuser')
// if the user is not logged, this method returns a falsy value
const user = request.getUserId() || 'World'
reply.send({
hello: `${user}!`,
})
})
})
```
- The library exports a function which creates the infrastructure ready to accept the definition of routes and decorators. Optionally can take a schema of the required environment variables, you can find the reference [here][fastify-env]. The function returned, `customService`, expects an async function to initialize and configure the `service`.
- `service` is a [Fastify instance](https://www.fastify.io/docs/latest/Server/), that is decorated by the library to help you interact with Mia-Platform resources. You can use *service* to register any Fastify routes, custom decorations and plugin, see [here][fastify-ecosystem] for a list of currently available plugins.

- `addRawCustomPlugin` is a function that requires the HTTP method, the path of the route and a handler. The handler can also be an [async function](https://www.fastify.io/docs/latest/Routes/#async-await).
Optionally you can indicate the JSONSchemas to validate the querystring, the parameters, the payload and the response.

### Examples
To get more info about Custom Services can you look at the [related section](./docs/CustomService.md).

Defining a new service that integrate with the platform is as simple as in this
[example](examples/basic/index.js).
Please see also a more [advanced example](examples/advanced/index.js) to see how to require
more environment variables, and to specify schema definitions for validation and swagger documentation.
## Environment Variables configuration
To works correctly, this library needs some specific environment variables:

For using one of the two example provided you can move to one of the two directories and run:
* `USERID_HEADER_KEY`
* `USER_PROPERTIES_HEADER_KEY`
* `GROUPS_HEADER_KEY`
* `CLIENTTYPE_HEADER_KEY`
* `BACKOFFICE_HEADER_KEY`
* `MICROSERVICE_GATEWAY_SERVICE_NAME`

When creating a new service from Mia-Platform DevOps Console, they come already defined but you can always change or add them anytime as described [in the DevOps console documentation](https://docs.mia-platform.eu/development_suite/api-console/api-design/services#environment-variable-configuration).
In local, the environment variables are defined
in this [file](examples/default.env).

Other variables can be specified by setting your envSchema when calling the plugin.

## Examples
You can see an [advanced example](examples/advanced/) to see different use cases of the library.

To see other examples of library use you can visit [GitHub dependant repository graph](https://github.com/mia-platform/custom-plugin-lib/network/dependents?package_id=UGFja2FnZS00NTc2OTY4OTE%3D) and check all packages that depends on it.

To run the [examples](examples) directly you can move to specific example folder and run:

```sh
npm run start:local
Expand All @@ -42,71 +103,31 @@ npm run start:local
This command will launch the service on `localhost:3000` with the environment variables defined
in this [file](examples/default.env).
Now you can consult the swagger documentation of the service at
[this](http://localhost:3000/documentation/) address.
[http://localhost:3000/documentation/](http://localhost:3000/documentation/).

### Local Development
# How to

To develop the service locally you need:
- Node 8+
* <a href="./docs/CustomService.md"><b>Create a Custom Service</b></a>
* <a href="./docs/Routes.md#declare-routes"><b>Declare routes</b></a>
* <a href="./docs/Decorators.md"><b>Add decorators</b></a>
* <a href="./docs/HTTPClient.md"><b>Call the other services on the Platform project</b></a>
* <a href="./docs/ApiDoc.md"><b>API documentation</b></a>
* <a href="./docs/Testing.md"><b>Testing</b></a>
* <a href="./docs/Logging.md#logging"><b>Logging</b></a>

To setup node, please if possible try to use [nvm][nvm], so you can manage multiple versions easily.
Once you have installed nvm, you can go inside the directory of the project and simply run
`nvm install`, the `.nvmrc` file will install and select the correct version
if you don’t already have it.
[17]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array

Once you have all the dependency in place, you can launch:
```shell
npm i
npm run coverage
```
[18]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String

This two commands, will install the dependencies and run the tests with the coverage report that you can view as an HTML
page in `coverage/lcov-report/index.html`.
[19]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object

## `rawCustomPlugin`
Defining a custom plugin that uses the platform’s services is as simple as
in this [helloWorld](examples/basic/helloWorld.js) example.
This library exports a function that optionally takes a schema of the required environment variables
(you can find the reference [here][fastify-env]).
This function returns a `customService` function, that expects an async function to initialize and configure
the service (provided as the only argument). This service is a [fastify][fastify] instance,
that also contains the method `addRawCustomPlugin`, that allows you to add a route.
Multiple routes can be added in this way.
For each route you have to specify an async handler. You should always return something (strings, objects, streams),
unless you set the response status code to 204. Please read [here][fastify-async] for further information
about async handlers.
You must also specify the http method, and the path of the hander. Optionally you can indicate the JSONSchemas
to validate the querystring, the parameters, the payload, the response.
In addition to validation, you will also have a swagger documentation available at the `/documentation/` path.

Thanks to TypeScript's type definitions, editors can actually provide autocompletion for the additional methods
of the request object such as `getUserId` or `getGroups` or `getUserProperties`

In the async initialization function you can also access the `fastify` instance, so you can register any plugin,
see [here][fastify-ecosystem] for a list of currently available plugins.
In addition, you can register additional [`content-type` parsers][fastify-parsers].

NB: the fifth parameter of `rawCustomPlugin` should be used wisely. See tests for that.

## Testing
CustomPlugin expose getDirectServiceProxy and getServiceProxy for testing purpose:
### getDirectServiceProxy
Import the function in you test:
``` javascript
const { getDirectServiceProxy } = require('@mia-platform/custom-plugin-lib')
const myServiceProxy = getDirectServiceProxy(MY_SERVICE_NAME)
```
all the options accepted by the getDirectServiceProxy can be passed (es: `{ port: CUSTOM_PORT }`).

### getServiceProxy
It need the MICROSERVICE_GATEWAY_SERVICE_NAME so you need to pass it like this:
``` javascript
const { getServiceProxy } = require('@mia-platform/custom-plugin-lib')
const myServiceProxy = getServiceProxy(MICROSERVICE_GATEWAY_SERVICE_NAME)
```
## Configuration
To use the library, you should specify the environment variables listed [here](index.js#L22),
other variables can be specified by setting your envSchema when calling the plugin.
[20]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean

[21]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise

[22]: https://developer.mozilla.org/docs/Web/API/Comment/Comment

[23]: https://daringfireball.net/projects/markdown/

[travis-svg]: https://travis-ci.org/mia-platform/custom-plugin-lib.svg?branch=master
[travis-org]: https://travis-ci.org/mia-platform/custom-plugin-lib
Expand Down
51 changes: 51 additions & 0 deletions docs/ApiDoc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# API documentation
Services developed with this library automatically also exposes the documentation of the routes and decorators that
are implemented. The documentation is specified using the [OpenAPI 2.0 standard](https://swagger.io/specification/v2/)
and exhibited through [Swagger](https://swagger.io).

Once the service is started, its documentation can be accessed at
route [`http://localhost:3000/documentation`](http://localhost:3000/documentation).

The specification of the request scheme
and responses to a route must conform to the format accepted by
[Fastify](https://www.fastify.io/docs/latest/Validation-and-Serialization).

## Example
```js
const customService = require('@mia-platform/custom-plugin-lib')()

const schema = {
body: {
type: 'object',
properties: {
someKey: { type: 'string' },
someOtherKey: { type: 'number' }
}
},

querystring: {
name: { type: 'string' },
excitement: { type: 'integer' }
},

params: {
type: 'object',
properties: {
par1: { type: 'string' },
par2: { type: 'number' }
}
},

headers: {
type: 'object',
properties: {
'x-foo': { type: 'string' }
},
required: ['x-foo']
}
}

module.exports = customService(async function exampleService(service) {
service.addRawCustomPlugin('GET', '/endpoint', function handler(request,reply) { ... }, schema)
})
```
30 changes: 30 additions & 0 deletions docs/CustomService.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Custom Service
A Custom Microservice is a service that receives HTTP requests, whose cycle of use and deploy is managed by the platform. A Custom Microservice encapsulates ad-hoc business logics that can be developed by any user of the platform. To know how manage your services in the DevOps Console see the [documentation](https://docs.mia-platform.eu/development_suite/api-console/api-design/services/)

The library exports a function which creates the infrastructure ready to accept the definition of routes and decorators.
The function optionally can take a schema of the required environment variables (you can find the reference [fastify-env](https://github.com/fastify/fastify-env).

## Example

```js
const customService = require('@mia-platform/custom-plugin-lib')({
type: 'object',
required: ['ENV_VAR'],
properties: {
ENV_VAR: { type: 'string' },
},
})
```
> **_More examples?_** Go [here](../examples/advanced/index.js#L46) to see another use cases.
You can configure the environment variables from DevOps console, in your service configuration. For further detail see [Mia-Platform documentation](https://docs.mia-platform.eu/development_suite/api-console/api-design/services/#environment-variable-configuration).

The function expects an async function to initialize and configure the `service`, a [Fastify instance](https://www.fastify.io/docs/latest/Server/).
You can access the environment variables values from `service.config`:
```js
module.exports = customService(async function handler(service) {
const { ENV_VAR } = service.config
...
})
```
Upon `service`, you can you can add [routes](Routes.md) and [decorators](Decorators.md).
Loading

0 comments on commit 7d1f12a

Please sign in to comment.