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

Refactor to use request library instead of got #8

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules
.vscode
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
language: node_js
node_js:
- "node"
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -7,8 +7,17 @@ style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.co
```js
const OpenFaaS = require('openfaas')

// Send in a gateway URL
const openfaas = new OpenFaaS('http://localhost:8080')

// Also supports any `request` library options
const clientWithAuth = new OpenFaaS('http://localhost:8080', {
auth: {
user: "jane",
pass: "123"
}
})
// Deploy
openfaas
.deploy(
'yolo', // name your function
@@ -18,6 +27,7 @@ openfaas
.then(x => console.log(x))
.catch(err => console.log(err))

// Invoke
openfaas
.invoke(
'yolo', // function name
@@ -28,11 +38,13 @@ openfaas
.then(x => console.log(x)) // handle response
.catch(err => console.log(err))

// Remove
openfaas
.remove('yolo')
.then(x => console.log(x)) // handle response
.catch(err => console.log(err))

// Chain functions together
openfaas
.compose('initial data', [
'func_nodeinfo',
140 changes: 88 additions & 52 deletions openfaas/index.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,53 @@
const path = require('path')
const got = require('got')
const request = require('request-promise')

class OpenFaaS {
constructor(gateway) {
this.gateway = gateway
}

list() {
const funcsPath = '/system/functions'
const options = {
/**
* Setup a new OpenFaas object
*
* @constructs
* @param {string} gateway - openfaas endpoint
* @param {object} requestOptions - any additional `request` library options
*/
constructor(gateway, requestOptions = {}) {
// Default request options
const defaultOptions = {
baseUrl: gateway,
resolveWithFullResponse: true,
json: true
}

return got(this.gateway + funcsPath, options)
// Allow overriding
const options = Object.assign(defaultOptions, requestOptions)

// Set default options for all requests
this.request = request.defaults(options)
}

/**
* Get a list of available functions and their data
*
* @returns {Promise<IncomingMessage>}
*/
list() {
return this.request.get('/system/functions')
}

/**
* Invoke a function
*
* @param {string} func - name of the function to invoke
* @param {object} data - function input
* @param {object} options
* @param {boolean} options.isJson - whether we are sending and expect JSON
* @param {boolean} options.isBinaryResponse - whether we expect binary (instead of utf8)
* @returns {Promise<IncomingMessage>}
*/
invoke(func, data, { isJson = false, isBinaryResponse = false } = {}) {
const funcPath = path.join('/function', func)
const functionEndpoint = path.join('/function', func)

const options = {
method: 'POST',
json: isJson,
encoding: (isBinaryResponse ? null : 'utf8')
}
@@ -28,73 +56,81 @@ class OpenFaaS {
options.body = data
}

return got(this.gateway + funcPath, options)
return this.request.post(functionEndpoint, options)
}

/**
* List a single function and its data
*
* @param {string} func - function name
* @returns {Promise<IncomingMessage>}
*/
inspect(func) {
return new Promise((resolve, reject) => {
return this.list()
.then(res => {
const funcs = res.body
for (let i = 0; i < funcs.length; i++) {
if (funcs[i].name === func) {
return resolve({ body: funcs[i], statusCode: res.statusCode })
}
}
resolve()
}).catch(reject)
})
const inspectEndpoint = path.join('/system/function/', func)

return this.request.get(inspectEndpoint)
}

/**
* Deploy a function
*
* @param {string} func - name for the function
* @param {string} image - image to use
* @param {object} options
* @param {string} options.network - name of the network to use
* @returns {Promise<IncomingMessage>}
*/
deploy(func, image, { network = 'func_functions' } = {}) {
const deployPath = path.join('/system/functions')

const options = {
method: 'POST',
json: true,
body: {
service: func,
image,
network
}
}

return got(this.gateway + deployPath, options)
return this.request.post('/system/functions', options)
}

/**
* Remove a function
*
* @param {string} name - function name
* @returns {Promise<IncomingMessage>}
*/
remove(name) {
const options = {
method: 'DELETE',
json: true,
body: {
functionName: name
}
}

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

compose(initial, funcs) {
const functions = funcs.map(func => {
return data => {
const options = {
method: 'POST',
body: data
}

const funcUrl = this.gateway + path.join('/function', func)
return got(funcUrl, options)
.then(res => Promise.resolve(res))
.catch(err => Promise.reject(err))
}
})

return functions.reduce(
(current, f) => {
return current.then(x => f(x.body))
},
new Promise(resolve => resolve(initial))
)
/**
* Allows you to chain functions together, passing the result from each
* as the input for the next (this takes place on the client side)
*
* @see https://github.com/openfaas/faas/blob/master/guide/chaining_functions.md
* @param {*} initial - input to send to the first function
* @param {array} funcs - list of functions to chain together
* @param {object} options - options to pass to each invoke
* @returns {Promise<IncomingMessage>}
*/
compose(initial, funcs, options = {}) {
// Start with a promise that returns our initial value as a response
let promise = Promise.resolve({ body: initial })

// Add on a .then() call for each of the functions to build the promise chain
for (const functionName of funcs) {
promise = promise.then(response => {
// Invoke the function using the response body as the input
return this.invoke(functionName, response.body, options)
})
}

return promise
}
}

Loading