自己文書化されたマイクロサービス(ArangoDB + swagger)

マイクロサービスのドキュメントを最新の状態に維持するには、開発において極度の規律と多大な人件費が必要です。 たとえば、GraphQLはドキュメントを作成するための非常に合理的なアプローチを提供します。ドキュメントはプログラムコードと密接にリンクされており、ドキュメントとドキュメント化されたサービスの100%コンプライアンスを保証します。 ただし、REST-APIに慣れている開発者向けのGraphQLの珍しいアプローチにより、この技術を実用的なアプリケーション開発に進めることは依然として困難です。 ここでは、ドキュメントとサービスの適合性の問題を長い間解決してきたSOAPを思い出すことができますが、複雑すぎるため、広範な開発者の間で定着しませんでした。



「従来の」REST-APIマイクロサービスを開発するときに、プログラムコードと同じ自己文書化を提供するマイクロサービスを開発するための技術スタックを見つけたいと思います。 そして、結局のところ、彼はすでに存在しています。



この小さな例に関与する俳優と出演者を定義します。



ArangoDBは、ドキュメント+グラフ指向のハイブリッドデータベースです。



UPD。 このデータベースをさらに詳しく知っていたことが、別の失望の理由でした。 判明したように、データベースが空きRAMによって制限されている非制限を超えると、データベースの速度が低下し始めます。サーバーとともに停止します。 同時に、新しいストレージエンジンへの移行がうまくいくというthat病な仮定が表明されましたが、まだ確認されていません。



Foxxは、ArangoDBデータベースに組み込まれたマイクロサービスフレームワークです。 JavaScriptエンジンで動作し、(nodejsとは異なり)無制限の数の並列スレッドで(互いにブロックしないで)同時に実行できます。その結果、promise / than / canchおよびasync / awaitコンストラクトは必要ありません。 サーバープロシージャを乱用することは推奨されないmongodbや、ストアドプロシージャも慎重に使用され、REST-APIを介してクライアント(ブラウザー、モバイルアプリケーションなど)と確実に対話しないリレーショナルデータベースとは対照的に、マイクロサービスフレームワークです。 Foxxは、httpプロトコルを介してクライアントと直接通信するマイクロサービスの開発専用に設計されました。



Swaggerは、開発者がRESTful Webサービスの開発、作成、文書化、および利用を支援するツールの大規模なエコシステムによってサポートされるオープンソースソフトウェア環境です。 ほとんどのユーザーはSwagger UIでSwaggerを識別しますが、Swaggerツールキットには、自動文書化、コード生成、テストケース生成のサポートが含まれています。



Swaggerにコード生成のサポートが含まれているという事実は、コードがドキュメント生成をサポートしている場合に取得したい状況とは逆の状況です。 ArangoDB + Foxxが提供するものには、反対のオプションが含まれています。 マイクロサービスコードがSwaggerの回路を生成する場合。 ただし、最小限の作業を行っただけで、これを自分で確認できます。



さらにアクションを実行するには、ArangoDBをインストールする必要があります。



  1. 管理パネルに移動し、新しいマイクロサービスを作成するためのアイテムを選択します。サービス->サービスの追加->新規。
  2. 開いたフォームに必要なフォームに入力します。 [ドキュメントコレクション]フィールドに、マイクロサービスの展開時に作成されるドキュメントコレクションの名前を追加します。 たとえば、猫。
  3. インストールボタンをクリックし、マイクロサービスをマウントするURLフィールドに入力します。


マイクロサービスをインストールするとき、「ドキュメントコレクション」フィールド(セクション2を参照)からのコレクションごとに、POST、GET、PUT、およびDELETEメソッドを使用してCRUD操作を実装するルートが作成されます。 ただし、これはメソッドのドラフトに過ぎず、新しいメソッドを変更、削除、追加できます。 マイクロサービス(猫)を作成するときにコレクションを1つ選択しましたが、そうしなかったかもしれませんが、後ですべてを手動で追加しました。



これで、catsコレクションにはCRUD操作のルートがあり、APIタブ([サービス]-> [マイクロサービス名]-> API)を選択して、データベース管理パネルからこれらのルートの呼び出しを開始できます。 このタブには、使い慣れたSwaggerインターフェースが含まれています。 また、管理パネルからだけでなく、通常のURLからアクセスできる外部ルートでSwaggerインターフェースを公開することもできます。



POST {"name": "Tom"}メソッドを使用してドキュメントをcatsコレクションに追加しようとすると、エラーのステータスが返されます。 なぜなら まだ定義していない名前フィールド。 したがって、引き続きArangoDB管理パネルを使用します。



4.より便利な開発のために、ArangoDBは開発モードを提供します。これは、[設定]タブで有効になります([サービス]-> [マイクロサービス名]->設定-セット開発)



これで、ワールドサービスのコードを変更し、結果をすぐに確認できます(追加の展開は不要です)。 マイクロサービスプログラムコードがあるディレクトリは、[情報]タブの管理パネルにあります([サービス]-> [マイクロサービス名]-> [情報])。



POSTルートの定義がどのように見えるか見てみましょう。



'use strict'; const dd = require('dedent'); const joi = require('joi'); const httpError = require('http-errors'); const status = require('statuses'); const errors = require('@arangodb').errors; const createRouter = require('@arangodb/foxx/router'); const Cat = require('../models/cat'); const cats = module.context.collection('cats'); const keySchema = joi.string().required() .description('The key of the cat'); const ARANGO_NOT_FOUND = errors.ERROR_ARANGO_DOCUMENT_NOT_FOUND.code; const ARANGO_DUPLICATE = errors.ERROR_ARANGO_UNIQUE_CONSTRAINT_VIOLATED.code; const ARANGO_CONFLICT = errors.ERROR_ARANGO_CONFLICT.code; const HTTP_NOT_FOUND = status('not found'); const HTTP_CONFLICT = status('conflict'); const router = createRouter(); module.exports = router; router.tag('cat'); router.post(function (req, res) { const cat = req.body; let meta; try { meta = cats.save(cat); } catch (e) { if (e.isArangoError && e.errorNum === ARANGO_DUPLICATE) { throw httpError(HTTP_CONFLICT, e.message); } throw e; } Object.assign(cat, meta); res.status(201); res.set('location', req.makeAbsolute( req.reverse('detail', {key: cat._key}) )); res.send(cat); }, 'create') .body(Cat, 'The cat to create.') .response(201, Cat, 'The created cat.') .error(HTTP_CONFLICT, 'The cat already exists.') .summary('Create a new cat') .description(dd` Creates a new cat from the request body and returns the saved document. `);
      
      







検証とドキュメントの両方は、オブジェクトスキーマの使用に基づいています。 名前フィールドを追加して、小さな変更を加えます。



 'use strict'; const _ = require('lodash'); const joi = require('joi'); module.exports = { schema: { // Describe the attributes with joi here _key: joi.string(), name: joi.string().description('cat`s name'), //    }, forClient(obj) { // Implement outgoing transformations here obj = _.omit(obj, ['_id', '_rev', '_oldRev']); return obj; }, fromClient(obj) { // Implement incoming transformations here return obj; } };
      
      







APIブックマークに移動すると、スキームが変更されたことを確認でき、名前フィールドを持つオブジェクトをcatsコレクションに追加できます。



apapacy@gmail.com

2018年11月12日。



All Articles