Skip to content
This repository has been archived by the owner on Feb 4, 2020. It is now read-only.

Refactor into ES6 class, add more tests and update docs #6

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 96 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,116 @@
style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo)
![OpenFaaS](https://img.shields.io/badge/openfaas-serverless-blue.svg)

##### Usage
# Installation

Add `openfaas` via `npm`

```
$ npm install openfaas --save
$ npm i openfaas
```

Example usage
# Example usage

```javascript
const OpenFaaS = require('openfaas')

const openfaas = new OpenFaaS('http://localhost:8080')
```

## Invoking functions

```js
openfaas
.invoke('function name', 'input')
.then(res => console.log(res.body))
.catch(err => console.log(err))
```

## Deploying functions

```js
openfaas
.deploy({
name: 'my-function', // name your function
network: 'func_functions', // choose your network (default func_functions)
image: 'hello-serverless' // choose the Docker image
})
.then(res => console.log(res))
.catch(err => console.log(err))
```
const OpenFaaS = require('./openfaas')

const openfaas = OpenFaaS('http://localhost:8080')
## Listing functions

openfaas.deploy(
'yolo', // name your function
'func_functions, // choose your network
'hello-serverless // choose the Docker image
)
.then(x => console.log(x))
.catch(err => console.log(err))
```js
openfaas.list()
.then(res => console.log(res.body)) // an array of the deployed functions
.catch(err => console.log(err))
```

## Removing functions

```js
openfaas.remove('my-function')
.then(res => console.log(res))
.catch(err => console.log(err))
```

openfaas.invoke(
'yolo', // function name
'hello world', // data to send to function
true //should response be JSON? optional. default is false
)
.then(x => console.log(x)) // handle response
.catch(err => console.log(err))
## Composing functions

openfaas.remove('yolo')
.then(x => console.log(x)) // handle response
.catch(err => console.log(err))
You have the ability to chain functions which rely on the previous execution's output by using `openfaas.compose()`, like this:

openfaas.compose('initial data', [
'func_nodeinfo',
'func_echoit',
'func_wordcount'
]
)
.then(x => console.log(x.body)) // handle final output
.catch(err => console.log(err))
```js
// the input for the first function
const markdown = `
# OpenFaaS chained functions example

[Find out more](https://github.com/openfaas-incubator/node-openfaas)
`

openfaas.compose(markdown, ['func_markdown', 'func_base64']).then(res => {
console.log(res.body)
})
```

```
PGgxPk9wZW5GYWFTIGNoYWluZWQgZnVuY3Rpb25zIGV4YW1wbGU8L2gxPgoKPHA+PGEgaHJlZj0i
aHR0cHM6Ly9naXRodWIuY29tL29wZW5mYWFzLWluY3ViYXRvci9ub2RlLW9wZW5mYWFzIiByZWw9
Im5vZm9sbG93Ij5GaW5kIG91dCBtb3JlPC9hPjwvcD4KCg==
```

This passes the output from the markdown renderer to the base64 function, and returns the output.

# Configuration

The OpenFaaS class constructor method accepts options in any of the following formats:
```js
const openfaas = new OpenFaaS('http://gateway:8080')
const openfaas = new OpenFaaS('http://gateway:8080', options)
const openfaas = new OpenFaaS(options)
```

`options` is an object with the following properties:
```js
{
gateway: 'gateway url', // (optional if passed as first parameter to the constructor)
user: 'basic auth username', // (optional)
pass: 'basic auth password' // (optional)
}
```

You can also add any of the options `got` supports since we just proxy them through. This includes all the options available through [`http.request`](https://nodejs.org/api/http.html#http_http_request_options_callback). One example of this could be HTTP basic authentication (to set this up on your OpenFaaS cluster check out [the official guides](https://github.com/openfaas/faas/tree/master/guide#a-foreword-on-security)).

```js
const openfaas = new OpenFaaS('http://localhost:8080', {
user: 'user',
pass: 'pass'
})
```

All the main methods (`invoke`, `deploy`, `list`, `remove` and `compose`) accept the same extra options parameter as above too.

In addition to this, `invoke` accepts a extra boolean option called `isBinaryResponse`. Setting this parameter to `true` in the options will mark the response as being binary content and will cause `invoke` to resolve to a response object who's body is a buffer.

##### ToDo
* Complete tests
* support additional request options for `got`
* support additional request options for `got` (**done** - see [!6](https://github.com/openfaas-incubator/node-openfaas/pull/6))
32 changes: 0 additions & 32 deletions openfaas/compose.js

This file was deleted.

24 changes: 0 additions & 24 deletions openfaas/deploy.js

This file was deleted.

104 changes: 92 additions & 12 deletions openfaas/index.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,96 @@
'use strict';
const path = require('path')
const got = require('got')

const deploy = require('./deploy');
const remove = require('./remove');
const invoke = require('./invoke');
const compose = require('./compose');
class OpenFaaS {
constructor(gateway, options) {
if (options) {
// they passed two arguments (url, options)
this.gateway = gateway
} else if (typeof gateway === 'string') {
// they passed a single string
options = {}
this.gateway = gateway
} else {
// they passed a single object
options = gateway
this.gateway = options.gateway
}

const OpenFaaS = url => ({
deploy: deploy(url),
remove: remove(url),
invoke: invoke(url),
compose: compose(url)
});
if (!this.gateway) throw new Error('Missing option `gateway`')

module.exports = OpenFaaS;
if (options.user) {
if (!options.pass) throw new Error('Missing option `pass`')
options.auth = `${options.user}:${options.pass}`
}

// save options for got
this.gotOptions = options
}

invoke(fn, data, options) {
options = options || {}

// merge our defaults and their passed options
const gotOptions = { ...this.gotOptions, ...options, method: 'POST' }

gotOptions.encoding = options.isBinaryResponse ? null : 'utf8'

if (data) gotOptions.body = data

return got(this.buildFunctionPath(fn), gotOptions)
}

deploy({ name, network, image }, options) {
const gotOptions = {
...this.gotOptions,
...(options || {}),
body: {
service: name,
network: network || 'func_functions',
image
},
json: true
}

return got.post(this.gateway + '/system/functions', gotOptions)
}

list(options) {
const gotOptions = { ...this.gotOptions, ...(options || {}), json: true }

return got.get(this.gateway + '/system/functions', gotOptions)
}

compose(data, functions, options) {
// no initial data
if (!functions) {
functions = data
data = undefined
}

// build an array of functions to be called with result from previous function
// [ function1(data), function2(data), ... ]
const calls = functions.map(f => data => this.invoke(f, data, options || {}))

return calls.reduce((chain, current) => {
return chain.then(res => current(res.body))
}, Promise.resolve({ body: data }))
}

remove(fn, options) {
const gotOptions = {
...this.gotOptions,
...(options || {}),
json: true,
body: { functionName: fn }
}

return got.delete(this.gateway + '/system/functions', gotOptions)
}

buildFunctionPath(fn) {
return this.gateway + path.join('/function', fn)
}
}

module.exports = OpenFaaS
25 changes: 0 additions & 25 deletions openfaas/invoke.js

This file was deleted.

21 changes: 0 additions & 21 deletions openfaas/remove.js

This file was deleted.

Loading