Contributing to hyper63 Part 2 - creating an adapter
Hello π,
Welcome back to the contributing to hyper63 series. In this session, we will create an adapter for our hyper63 port
.
If you have not done the part 1 of the tutorial, you can find part 1 here:
What is a hyper63 adapter? π
An adapter is the implementation details of a given hyper63 port. If the port is a cache api, then an adapter would be an adapter to uses the redis service. The adapter contains the specific details of a given service where the port is more general and provides the common api on how an adapter should expose its features.
Greeting Echo Adapter
We want to teach the process of creating an adapter and not get caught up in a specific service, so our adapter will be a greeting echo adapter. The port is called echo and contains one method called echo
which is a function that takes a string as an argument and returns a Promise
that returns a String
. Our greeting adapter will implement this echo port and return a promise with the text 'Hello ' plus whatever was passed as a string. For Example, if 'World' was passed as a string then our adapter will return 'Hello World'. π
Setting up our project βοΈ
mkdir hyper63-adapter-greeting
cd hyper63-adapter-greeting
yarn init -y
yarn add -D tape
yarn add -D @hyper63/adapter-tester
yarn add -D @hyper63/port-echo
open package.json
in your code editor π»
and add "type": "module"
to enable ESM
{
...
"type": "module"
}
index.js
create an index.js
file and open it in your code editor π»
The index file is going to implement the adapter header that is used to properly install the adapter in hyper63.
import adapter from './adapter.js'
export default function () {
return {
id: 'greeting',
port: 'echo',
load: env => env,
link: env => _ => adapter(env)
}
}
The main adapter function must return an object that contains the following properties:
- id - name of the adapter
- port - name of the port the adapter is implementing
- load - this function handles any configuration that may need to be passed to the adapter
- link - this function handles the actual adapter injection to hyper63
adapter.js
create an adapter.js
file and open it in your code editor π»
export default function (env) {
return {
echo: s => Promise.resolve(`Hello ${s}`)
}
}
Testing your adapter
First we will create a unit test for the adapter implementation.
create an adapter_test.js
file and open your code editor π»
import { default as test } from 'tape'
import adapter from './adapter.js'
test('echo hello world', t => {
t.plan(1)
const a = adapter()
t.equal('Hello World', a.echo('World'))
})
lets also create an integration test
create an index_test.js
file and open your code editor π»
import { default as test } from 'tape'
import greetingsAdapter from './index.js'
import port from 'hyper63-port-echo'
test('ok', async t => {
t.plan(1)
try {
const greetings = greetingsAdapter()
const env = greetings.load()
const adapter = greetings.link(env)()
const a = port(adapter)
const res = await a.echo('World')
t.equal(res, 'Hello World')
} catch (e) {
console.log(e)
t.ok(false)
}
})
Setup Github Action
Lets setup a Github action to run our tests on every push
create a test runner file test.js
import indexTest from './index_test.js'
import adapterTest from './adapter_test.js'
modify the package.json
file
{
...
"scripts": {
"test": "node test.js"
}
}
create a new directory .github/workflows
mkdir -p .github/workflows
create a new file in the .github/workflows
directory called test.yml
name: test greetings adapter
on: push
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x]
steps:
- uses: actions/checkout@v2
- name: Use NodeJS ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: yarn
- run: yarn test
env:
CI: true
README
create a README.md
file
# README
hyper63 greetings adapter for the hyper63 echo port
This adapter is used in hyper63 to support for the echo port
## Example
``` js
import echoPort from 'hyper63-port-echo'
import greetings from 'hyper63-adapter-greetings'
export default {
app: express,
adapters: [
{ port: echoPort, plugins: [greetings()] }
]
}
```
Deploy to Github
git init
echo node_modules > .gitignore
git add .
git commit -m 'first commit'
gh repo create hyper63-adapter-greetings
git push origin master
Publish to NPM
change the name of the package.json
to include your namespace
{
"name": "@username/hyper63-adapter-greetings"
...
}
run npm publish
npm publish --access public
Summary
This tutorial walked us through creating a simple adapter for a hyper63 port, the adapter process is two phases, the implementation of the port specification and the wrapper object that provides the linking information for the hyper63 core engine.
In part 3 of this series we will cover how to attach your new port and adapter to the hyper63 core module and load up your own hyper63 service.