クイックスタートガイド
✨ 以下のチュートリアル手順では、Nodeblocksを使って新しいサービスリポジトリを作成する方法を案内します。
このチュートリアルを完了すると、以下が手に入れるはずです:
- AuthおよびUserブロックのパッケージがインストールされた、必要に応じてカスタマイズできる状態のgitリポジトリ
- これらのブロックのデータを含むMongoDBサーバー
- AuthサービスとUserサービス両方がローカルで動いていて、Postman経由のリクエストに応答している状態
このガイドではデプロイについて取り上げません。完全にローカル開発に焦点を当てています。 デプロイガイド(手動またはNodeblocks Cloudを使用)については、「次の段階」のセクションを参照してください
前提条件
- ローカルのNodeblocks開発はどんなOSでも行えますが、macOSやLinux環境が理想的です。
- IDEはVSCodeをお勧めします。
パッケージ | バージョン |
---|---|
node | >=16 |
npm | >=9 |
git | >=2 |
BasalのNPMインストールトークン
始める前に、まずはベーセル社からNodeblocksをダウンロードする権限を与えるNPMトークンの提供は必要です。
このトークンはnpm_
で始まり、バックエンドSDKや各Nodeblocksのブロックなどのパッケージにアクセスできるようになります。"
Dockerか、MongoDBか
各NodeblocksのブロックはデフォルトのデータベースとしてMongoDBを使用しています。 ブロックサービスの初期設定およびローカルでの実行に必要です。ローカル環境では、選択肢は二つあります。 MongoDBデータベースをdocker(またはpodman)コンテナ内で実行するか、直接ホストマシンにインストールを行うかです。
これら以外に、事前にクラウドにデプロイされた既存のMongoDBに接続する事も可能です。
Dockerのインストール方
docker run hello-world
podman machine init # macOSやWindows環境使用者
podman machine start
podman run hello-world
MongoDBのインストール方
- MongoDBをインストール
mongosh
を使って動いているDBに接続出来るかを確認
リポジトリ作成
- サービス用に新しいgitリポジトリを作成して、初期設定を行う
mkdir my-project
cd my-project
git init
npx gts init
git add . && git commit
npx gts init
はGoogleのリンティングおよびフォーマットのガイドラインに従った初期状態の
TypeScriptプロジェクトを作成します。必要に応じて設定を変更しても問題ありません。
- お好みのIDEでこのリポジトリを開く
code .
.gitignore
のファイルを作成して、一般的に無視されるフォルダやファイルを記入
*.log
.DS_Store
.docusaurus
.cache-loader
.env
node_modules
build
dist
scratch.js
coverage
.vscode/settings.json
.npmrc
のファイルを作成して、ベーセル社からもらったNodeblocksのNPMトークンを記入
engine-strict=true
@basaldev:registry=https://registry.npmjs.org
//registry.npmjs.org/:_authToken=${NODEBLOCKS_DEV_TOKEN}
${NODEBLOCKS_DEV_TOKEN}
をトークンで置き換えるか、.bashrc
または.zsrc
に
export NODEBLOCKS_DEV_TOKEN=<token>
を追加することで新しい環境変数を追加してください
.env
のファイルを作成して、デフォルトの環境変数を追加してください。.env.default
にコピーして、 他のメンバーが使えるようにコミットしてください。必ずDATABASE_URL
などの変数ををご自身の 都合に合わせて変更してください
PORT=8080
DATABASE_URL=mongodb://dev:dev@localhost:27017
USER_SERVICE_ENDPOINT=http://localhost:8081
AUTH_SERVICE_ENDPOINT=http://localhost:8080
AUTH_ENC_SECRET=<20文字以上の共有鍵を記述してください>
AUTH_SIGN_SECRET=<20文字以上の共有鍵を記述してください>
dotenv
パッケージをインストールして、サービス実行のためにpackage.json
にコマンドを追加
npm install --save dotenv
{
...
"scripts": {
...
"start": "node -r dotenv/config dist/index.js"
},
}
- このリポジトリ用に
tsconfig.json
の設定を変更
{
"extends": "./node_modules/gts/tsconfig-google.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist",
"esModuleInterop": true
},
"include": [
"src/**/*.ts",
"test/**/*.ts"
]
}
MongoDBの構築
MongoDBの実行環境はローカルマシーンやクライドの場合、ここで設定は以上です。 ただし、dockerおよびpodman使用の場合、ローカル開発のためにコンテナの標準化を行った方が 役に立つのかもしれません。
docker-compose.yml
ファイルを作成
version: '3.1'
services:
mongo:
image: mongo
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: dev
MONGO_INITDB_ROOT_PASSWORD: dev
ports:
- 27017:27017
docker-compose up
またはpodman compose up
を実行してデータベースサーバーを立ち上げる- ローカル開発に注力する場合、以下のフェイクサービスも追加する方が便利かもしれません 実のサービスを使う場合はスキップしてください。
services:
# GCSのフェイクサーバー
# (AWSのバッケットも似たようなコンテナも存在します)
gcs:
image: fsouza/fake-gcs-server
volumes:
- ./test/data/gcs/data:/data
- ./test/data/gcs/storage:/storage
command: -scheme http -public-host ${URL:-localhost}:4443
ports:
- 4443:4443
# ローカルMongoDBを自分で弄ることをできるウェブUI
mongo-express:
image: mongo-express
restart: always
ports:
- 8081:8081
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: dev
ME_CONFIG_MONGODB_ADMINPASSWORD: dev
ME_CONFIG_MONGODB_URL: mongodb://dev:dev@mongo:27017/
# メールプロバイダのフェイク
sendgrid:
image: ghashange/sendgrid-mock:1.9.0
environment:
API_KEY: sendgrid-api-key
ports:
- 7000:3000
Authのブロックを実装
- NPMパッケージのインストール
npm install --save @basaldev/blocks-auth-service
- 下記のコードで
index.ts
置き換えて実装
import {
createNodeblocksAuthApp,
defaultAdapter,
} from '@basaldev/blocks-auth-service';
function getEnvironmentVariable(name: string, defaultValue: string) {
const value = process.env[name] || defaultValue;
if (value === undefined) {
throw new Error(`Environment Variable ${name} is not set`);
}
return value;
}
const PORT = Number(getEnvironmentVariable('PORT', '8080'));
const DATABASE_URL = getEnvironmentVariable('DATABASE_URL', '');
const USER_SERVICE_ENDPOINT = getEnvironmentVariable(
'USER_SERVICE_ENDPOINT',
''
);
const AUTH_SERVICE_ENDPOINT = getEnvironmentVariable(
'AUTH_SERVICE_ENDPOINT',
''
);
const AUTH_ENC_SECRET = getEnvironmentVariable('AUTH_ENC_SECRET', '');
const AUTH_SIGN_SECRET = getEnvironmentVariable('AUTH_SIGN_SECRET', '');
void createNodeblocksAuthApp({
corsOrigin: [/.*/],
}).startService({
PORT: Number(PORT),
env: 'development',
domain: AUTH_SERVICE_ENDPOINT,
adapter: defaultAdapter.createAuthDefaultAdapter(
{
authEncSecret: AUTH_ENC_SECRET,
authSignSecret: AUTH_SIGN_SECRET,
enableRefreshToken: false,
tokenExpireTime: {
accessToken: '2h',
onetimeToken: '5m',
refreshToken: '1d',
},
},
DATABASE_URL,
USER_SERVICE_ENDPOINT
),
});
- サービスをビルドして立ち上げる
npm run compile
npm run start
正常な動作だと、ターミナルで以下が表示されるはずです:
[2023-09-28T05:41:22.518Z] INFO: NODEBLOCKS_AUTH_SERVICE/16920 on <your-pc>: Starting (adapter=nb-auth-default-adapter, port=8080)
これで立ち上げました!ローカル環境でNodeblocksのブロックが稼働状態です。
動作の確認
エンドポイントを手動でテストする時はPostmanをお勧めします。 設定した後は、以下のエンドポイントに新しくリクエストを実行してください:
GET http://localhost:8080/ping
実行すると、以下のようなレスポンスが返ってくるはずです:
{
"packageInfo": {
"gitCommitHash": "",
"sdkVersion": "1.3.0",
"serviceAdapterAPIVersion": "^1.1.0",
"serviceName": "@basaldev/blocks-auth-service",
"serviceVersion": "1.2.0"
},
"status": "ok"
}
Authブロックが正常に稼働して、リクエストを処理していることです。 次はログインのリクエストを試しますね。
POST http://localhost:8080/login
{
"email": "email@example.com",
"password": "password1234",
"fingerprint": "<fingerprintを選んでください>"
}
fingerprint(指紋)はご自分で決めた値で、ログインした後に全てのリクエストで渡す必要があります。 このfingerprintはこのデバイスが最初にアクセストークンをリクエストをした事を証明します。
以下のレスポンスが返ってきます:
{
"code": "INTERNAL_REQUEST_ERROR",
"details": [],
"message": "error requesting post http://localhost:8081/users/check_password"
}
なぜこのエラーが出てしまうのか。原因はパスワードが正しいのかを確認するため、Authブロックが
Userブロックとの連携する必要があるからです。USER_SERVICE_ENDPOINT
の変数を提供しましたが、
現時点ではUserブロックは稼働してません。次はUserブロックのサービスを立ち上げましょう。
デフォルトではAuthブロックはパスワードの検証としてUserブロックが必要ですが、これはハードコードされた 条件ではありません。独自の依存関係を注入することで、パスワードチェックの処理を自由に変えられます。 Customizationを参照してください。
Userブロックの実装
サービスを整理する方法として、サービスごとのリポジトリを使用するか、 または全体的なモノレポを使用することが。それぞれの方法には利点があります。
サービスごとのリポジトリ | モノリポジトリ | |
---|---|---|
利点 | Nodeblocks Cloudと連携可能、整理簡単、個別にデプロイ可能 | 全サービス同時にデプロイ、標準化がより便利 |
欠点 | サービス同士で不一致が発生する可能性がある | Nodeblocks Cloudと連携出来ない、個別のデプロイが難しくなる |
このチュートリアルではサービスごとのリポジトリを使います。
- 前に作ったauthのリポジトリを使って新しいリポジトリを作成(事前にnode_modulesを削除する方がいいのかもしれません)
cd ..
cp -r my-project my-project-user
- authパッケージを削除してuserの方をインストール
npm uninstall @basaldev/blocks-auth-service
npm install --save @basaldev/blocks-user-service
.env
と.env.default
のファイルを更新
PORT=8081
DATABASE_URL=mongodb://dev:dev@localhost:27017
USER_SERVICE_ENDPOINT=http://localhost:8081
AUTH_SERVICE_ENDPOINT=http://localhost:8080
ORGANIZATION_SERVICE_ENDPOINT=http://localhost:8083
AUTH_ENC_SECRET=<write a secret over 20 characters>
AUTH_SIGN_SECRET=<write a secret over 20 characters>
# バッケット設定
BUCKET_NAME=my_bucket
MAX_ATTACHMENT_SIZE_MB=10
ALLOWED_ATTACHMENT_CONTENT_TYPES=jpg,png,gif
# メールの設定
SEND_GRID_API_KEY=sendgrid-api-key
SENDER=noreply@mycompany.co.jp
VENDOR_EMAIL_URL=http://localhost:3000/email/verify
CUSTOMER_EMAIL_URL=http://localhost:3000/waiting-email-verify
VENDOR_RESET_PASSWORD_URL=http://localhost:3000/waiting_reset_password
CUSTOMER_RESET_PASSWORD_URL=http://localhost:3000/waiting_reset_password
ACCEPT_INVITATION_URL=http://localhost:3000/accept_invitation
index.ts
を置き換える
import {
UserDefaultAdapterOptions,
createNodeblocksUserApp,
createUserDefaultAdapter,
} from '@basaldev/blocks-user-service';
function getEnvironmentVariable(name: string, defaultValue: string) {
const value = process.env[name] || defaultValue;
if (value === undefined) {
throw new Error(`Environment Variable ${name} is not set`);
}
return value;
}
const PORT = Number(getEnvironmentVariable('PORT', '8081'));
const DATABASE_URL = getEnvironmentVariable('DATABASE_URL', '');
const SEND_GRID_API_KEY = getEnvironmentVariable('SEND_GRID_API_KEY', '');
const AUTH_SERVICE_ENDPOINT = getEnvironmentVariable(
'AUTH_SERVICE_ENDPOINT',
''
);
const ORGANIZATION_SERVICE_ENDPOINT = getEnvironmentVariable(
'ORGANIZATION_SERVICE_ENDPOINT',
''
);
const AUTH_ENC_SECRET = getEnvironmentVariable('AUTH_ENC_SECRET', '');
const AUTH_SIGN_SECRET = getEnvironmentVariable('AUTH_SIGN_SECRET', '');
const BUCKET_NAME = getEnvironmentVariable('BUCKET_NAME', '');
const MAX_ATTACHMENT_SIZE_MB = getEnvironmentVariable(
'MAX_ATTACHMENT_SIZE_MB',
''
);
const SENDER = getEnvironmentVariable('SENDER', '');
async function main() {
const adapter: UserDefaultAdapterOptions = {
encSecret: AUTH_ENC_SECRET || '',
emailConfig: {
sender: SENDER,
inviteUser: {
enabled: false,
},
verifyEmail: {
enabled: false,
},
resetPassword: {
enabled: false,
},
},
signSecret: AUTH_SIGN_SECRET || '',
allowedAttachmentContentTypes: ['image/jpeg', 'image/png', 'image/gif'],
maxAttachmentSizeMB: Number(MAX_ATTACHMENT_SIZE_MB),
};
await createNodeblocksUserApp({
corsOrigin: [/.*/],
}).startService({
PORT,
env: 'development',
adapter: createUserDefaultAdapter(
adapter,
DATABASE_URL,
BUCKET_NAME,
AUTH_SERVICE_ENDPOINT,
ORGANIZATION_SERVICE_ENDPOINT,
{
authEncSecret: AUTH_ENC_SECRET || '',
authSignSecret: AUTH_SIGN_SECRET || '',
},
{
sendGridApiKey: SEND_GRID_API_KEY,
}
),
});
}
void main();
- サービスをビルドして立ち上げる
npm run compile
npm run start
- 立ち上げ完了のメッセージを確認したら、Postmanで新しいリクエストを作成してUserサービスにpingを送ってみる
GET http://localhost:8081/ping
以下のようなレスポンスが返ってきます:
{
"packageInfo": {
"gitCommitHash": "",
"sdkVersion": "1.3.0",
"serviceAdapterAPIVersion": "^1.1.0",
"serviceName": "@basaldev/blocks-user-service",
"serviceVersion": "1.3.0"
},
"status": "ok"
}
またAuthサービスにログインのリクエストを送ると、新しいエラーが出てきます:
{
"code": "login_error",
"details": [],
"message": "email or password is wrong"
}
ユーザーの作成
Authサービスでログイン出来るようにユーザーを作成しましょう。
POST http://localhost:8081/users
{
"name": "my-user",
"email": "email@example.com",
"password": "password1234",
"typeId": "000"
}
予想レスポンス:
{
"id": "...",
"email": "email@example.com",
"name": "my-user",
"typeId": "000",
"emailVerified": false,
...
}
またログインのリクエストを送ると、以下のレスポンスが返ってくるはずです:
{
"accessToken": "...",
"userId": "..."
}
アクセストークンの使用方法
Let's use your token to fetch your user info. Perform the following request, with the following headers:
GET http://localhost:8081/users/<ユーザーID>
Authorization: Bearer <accessTokenの値>
x-nb-fingerprint: <ログインに使ったfingerprint>
ユーザー作成のリクエストと同じレスポンスが返ってくるはずです。
次の段階
🎉 おめでとうございます!AuthとUserのブロックを使用して二つのサービスの立ち上げて、gitリポジトリも作りました。 次の段階に進むにはいくつかの選択肢があります: