From 73ee548de1258100386b3c7fe9ad4d90f795f6c7 Mon Sep 17 00:00:00 2001 From: "S. Amir Mohammad Najafi" Date: Thu, 12 Jan 2023 18:12:44 +0330 Subject: [PATCH] fea(form): new micro service --- services/form/README.md | 7 +++ services/form/demo.http | 17 ++++++++ services/form/package.json | 65 ++++++++++++++++++++++++++++ services/form/src/config.ts | 20 +++++++++ services/form/src/index.ts | 7 +++ services/form/src/lib/nano-server.ts | 5 +++ services/form/src/lib/storage.ts | 7 +++ services/form/src/route/home.ts | 9 ++++ services/form/src/route/put.ts | 39 +++++++++++++++++ services/form/src/route/storage.ts | 31 +++++++++++++ services/form/tsconfig.json | 20 +++++++++ tsconfig.json | 1 + 12 files changed, 228 insertions(+) create mode 100644 services/form/README.md create mode 100644 services/form/demo.http create mode 100644 services/form/package.json create mode 100644 services/form/src/config.ts create mode 100644 services/form/src/index.ts create mode 100644 services/form/src/lib/nano-server.ts create mode 100644 services/form/src/lib/storage.ts create mode 100644 services/form/src/route/home.ts create mode 100644 services/form/src/route/put.ts create mode 100644 services/form/src/route/storage.ts create mode 100644 services/form/tsconfig.json diff --git a/services/form/README.md b/services/form/README.md new file mode 100644 index 000000000..ec65d6ecb --- /dev/null +++ b/services/form/README.md @@ -0,0 +1,7 @@ +# Form Service + +Distributed simple and fast form nanoservice base on [@alwatr/storage-server](../storage-server/). + +## How to use + +Check [demo.http](demo.http). diff --git a/services/form/demo.http b/services/form/demo.http new file mode 100644 index 000000000..04f41b4f8 --- /dev/null +++ b/services/form/demo.http @@ -0,0 +1,17 @@ +@apiUrl = http://127.0.0.1:8000 +@apiVersion = v0 +@token = YOUR_SECRET_TOKEN + +### home +GET {{apiUrl}}/ + +### Add new form +PUT {{apiUrl}}/ +Authorization: Bearer {{token}} +Content-Type: application/json + +{ + "filed1": "test1", + "filed2": "test2", + "filed13": "test3" +} diff --git a/services/form/package.json b/services/form/package.json new file mode 100644 index 000000000..ac83ea461 --- /dev/null +++ b/services/form/package.json @@ -0,0 +1,65 @@ +{ + "name": "@alwatr/form", + "version": "0.27.0", + "description": "Alwatr Form API Microservice, Distributed simple and fast form nanoservice base on @alwatr/storage-server", + "type": "module", + "keywords": [ + "api", + "form", + "microservice", + "nanoservice", + "typescript", + "alwatr" + ], + "author": "S. Ali Mihandoost (https://ali.mihandoost.com)", + "contributors": [ + "S. Amir Mohammad Najafi (https://njfamirm.ir)" + ], + "license": "MIT", + "private": true, + "engines": { + "node": ">=19.0.0", + "npm": ">=8.0.0", + "yarn": ">=1.22.0" + }, + "repository": { + "type": "git", + "url": "https://github.com/AliMD/alwatr", + "directory": "services/form" + }, + "homepage": "https://github.com/AliMD/alwatr/tree/main/services/form#readme", + "bugs": { + "url": "https://github.com/AliMD/alwatr/issues" + }, + "scripts": { + "b": "yarn build", + "c": "yarn clean", + "cb": "run-s clean build", + "s": "yarn start", + "w": "yarn watch", + "start": "NODE_OPTIONS=--enable-source-maps run-s clean build serve", + "build": "yarn build:es --analyze=verbose", + "build:ts": "tsc --build", + "build:es": "esbuild src/index.ts --platform=node --target=node19 --bundle --format=esm --minify --sourcemap --outdir=dist --out-extension:.js=.mjs", + "clean": "rimraf dist build .tsbuildinfo **/*.{d.ts,map} src/**/*.{js,cjs,mjs}", + "serve": "node --enable-source-maps dist/index.mjs", + "serve:debug": "node --inspect --enable-source-maps dist/index.mjs", + "watch": "run-s clean build && run-p watch:es watch:node", + "watch:node": "nodemon -w dist/ --enable-source-maps dist/index.mjs", + "watch:debug-node": "nodemon -w dist/ --inspect --enable-source-maps dist/index.mjs", + "watch:ts": "yarn build:ts --watch --preserveWatchOutput", + "watch:es": "yarn build:es --watch" + }, + "devDependencies": { + "@alwatr/logger": "^0.27.0", + "@alwatr/nano-server": "^0.27.0", + "@alwatr/type": "^0.27.0", + "@alwatr/storage-client": "^0.27.0", + "@types/node": "^18.11.18", + "esbuild": "^0.16.14", + "nodemon": "^2.0.20", + "npm-run-all": "^4.1.5", + "rimraf": "^3.0.2", + "typescript": "^4.9.4" + } +} diff --git a/services/form/src/config.ts b/services/form/src/config.ts new file mode 100644 index 000000000..79d820472 --- /dev/null +++ b/services/form/src/config.ts @@ -0,0 +1,20 @@ +import {createLogger} from '@alwatr/logger'; + +export const logger = createLogger('form'); + +export const config = { + nanoServer: { + host: process.env.HOST ?? '0.0.0.0', + port: process.env.PORT != null ? +process.env.PORT : 8000, + allowAllOrigin: true, + accessToken: process.env.ACCESS_TOKEN ?? 'YOUR_SECRET_TOKEN', + }, + storage: { + name: process.env.STORAGE_NAME ?? 'form', + host: process.env.STORAGE_HOST ?? '127.0.0.1', + port: process.env.STORAGE_PORT != null ? +process.env.STORAGE_PORT : 9000, + token: process.env.STORAGE_TOKEN ?? 'YOUR_SECRET_TOKEN', + }, +}; + +logger.logProperty('config', config); diff --git a/services/form/src/index.ts b/services/form/src/index.ts new file mode 100644 index 000000000..e138b3c33 --- /dev/null +++ b/services/form/src/index.ts @@ -0,0 +1,7 @@ +import {logger} from './config.js'; + +import './route/home.js'; +import './route/put.js'; +import './route/storage.js'; + +logger.logOther('..:: Alwatr Comment Nanoservice API ::..'); diff --git a/services/form/src/lib/nano-server.ts b/services/form/src/lib/nano-server.ts new file mode 100644 index 000000000..593467ef5 --- /dev/null +++ b/services/form/src/lib/nano-server.ts @@ -0,0 +1,5 @@ +import {AlwatrNanoServer} from '@alwatr/nano-server'; + +import {config} from '../config.js'; + +export const nanoServer = new AlwatrNanoServer(config.nanoServer); diff --git a/services/form/src/lib/storage.ts b/services/form/src/lib/storage.ts new file mode 100644 index 000000000..aede224e2 --- /dev/null +++ b/services/form/src/lib/storage.ts @@ -0,0 +1,7 @@ +import {AlwatrStorageClient} from '@alwatr/storage-client'; + +import {config} from '../config.js'; + +import type {AlwatrDocumentObject} from '@alwatr/type'; + +export const storageClient = new AlwatrStorageClient(config.storage); diff --git a/services/form/src/route/home.ts b/services/form/src/route/home.ts new file mode 100644 index 000000000..620e6f7ab --- /dev/null +++ b/services/form/src/route/home.ts @@ -0,0 +1,9 @@ +import {nanoServer} from '../lib/nano-server.js'; + +nanoServer.route('GET', '/', () => ({ + ok: true, + data: { + app: 'Alwatr Form API Microservice', + message: 'Hello ;)', + }, +})); diff --git a/services/form/src/route/put.ts b/services/form/src/route/put.ts new file mode 100644 index 000000000..dc10f1814 --- /dev/null +++ b/services/form/src/route/put.ts @@ -0,0 +1,39 @@ +import {config, logger} from '../config.js'; +import {nanoServer} from '../lib/nano-server.js'; +import {storageClient} from '../lib/storage.js'; + +import type {AlwatrConnection, AlwatrServiceResponse} from '@alwatr/nano-server'; +import type {AlwatrDocumentObject} from '@alwatr/type'; + +nanoServer.route('PUT', '/', setForm); + +async function setForm(connection: AlwatrConnection): Promise { + logger.logMethod('setForm'); + + connection.requireToken(config.nanoServer.accessToken); + + const bodyJson = await connection.requireJsonBody(); + + bodyJson.id ??= 'auto_increment'; + + try { + return { + ok: true, + data: await storageClient.set(bodyJson), + }; + } + catch (_err) { + const err = _err as Error; + logger.error('setForm', err.message || 'storage_error', err); + return { + ok: false, + statusCode: 500, + errorCode: 'storage_error', + meta: { + name: err.name, + message: err.message, + cause: err.cause, + }, + }; + } +} diff --git a/services/form/src/route/storage.ts b/services/form/src/route/storage.ts new file mode 100644 index 000000000..338102eda --- /dev/null +++ b/services/form/src/route/storage.ts @@ -0,0 +1,31 @@ +import {config, logger} from '../config.js'; +import {nanoServer} from '../lib/nano-server.js'; +import {storageClient} from '../lib/storage.js'; + +import type {AlwatrConnection, AlwatrServiceResponse} from '@alwatr/nano-server'; + +nanoServer.route('GET', '/storage', getFormStorage); + +async function getFormStorage(connection: AlwatrConnection): Promise { + logger.logMethod('getFormStorage'); + + connection.requireToken(config.nanoServer.accessToken); + + try { + return await storageClient.getStorage(); + } + catch (_err) { + const err = _err as Error; + logger.error('getFormStorage', err.message || 'storage_error', err); + return { + ok: false, + statusCode: 500, + errorCode: 'storage_error', + meta: { + name: err.name, + message: err.message, + cause: err.cause, + }, + }; + } +} diff --git a/services/form/tsconfig.json b/services/form/tsconfig.json new file mode 100644 index 000000000..1f3a43b59 --- /dev/null +++ b/services/form/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "../../tsconfig.base", + "compilerOptions": { + "target": "ESNext", + "composite": true, + "tsBuildInfoFile": ".tsbuildinfo", + "rootDir": "src", + "outDir": "build" + // "noEmit": true + }, + + "include": ["src/**/*.ts"], + "exclude": [], + "references": [ + {"path": "../../core/nano-server"}, + {"path": "../../core/logger"}, + {"path": "../../core/type"}, + {"path": "../../core/storage-client"} + ] +} diff --git a/tsconfig.json b/tsconfig.json index 5a202c68f..50958900c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -33,6 +33,7 @@ // services {"path": "./services/comment"}, + {"path": "./services/form"}, {"path": "./services/starter"}, {"path": "./services/storage-server"}, {"path": "./services/telegram-notifier"},