マークダウンをHTMLに変換するNode.jsExpressAPIの構築
公開: 2022-03-10Markdownは、マークされたテキストをさまざまな形式に変換できる軽量のテキストマークアップ言語です。 Markdownを作成する当初の目標は、人々が「読みやすく、書きやすいプレーンテキスト形式を使用して書く」ことを可能にし、オプションでそれを構造的に有効なXHTML(またはHTML)に変換できるようにすることでした。 現在、WordPressがMarkdownをサポートしているため、このフォーマットはさらに広く使用されるようになりました。
この記事を書く目的は、Node.jsとExpressフレームワークを使用してAPIエンドポイントを作成する方法を示すことです。 これを学習するコンテキストは、Markdown構文をHTMLに変換するアプリケーションを構築することです。 また、アプリケーションの誤用を防ぐために、APIに認証メカニズムを追加します。
MarkdownNode.jsアプリケーション
「MarkdownConverter」と呼ばれる小さなアプリケーションを使用すると、Markdownスタイルのテキストを投稿してHTMLバージョンを取得できます。 アプリケーションはNode.jsExpressフレームワークを使用して作成され、変換要求の認証をサポートします。
アプリケーションを小さな段階で構築します。最初にExpressを使用してスキャフォールドを作成し、次に認証などのさまざまな機能を追加します。 それでは、スキャフォールドを作成してアプリケーションを構築する初期段階から始めましょう。
ステージ1:Expressのインストール
システムにNode.jsがすでにインストールされていると仮定して、アプリケーションを保持するディレクトリを作成し(「 markdown-api
」と呼びます)、そのディレクトリに切り替えます。
$ mkdir markdown-api $ cd markdown-api
npm initコマンドを使用して、アプリケーションのpackage.jsonファイルを作成します。 このコマンドは、アプリケーションの名前やバージョンなど、いくつかの入力を求めるプロンプトを表示します。
今のところ、 Enterキーを押すだけで、ほとんどのデフォルトを受け入れることができます。 デフォルトのエントリポイントファイルをindex.jsとして使用しましたが、好みに応じてapp.jsまたはその他のファイルを試すことができます。
次に、Expressをmarkdown-api
ディレクトリにインストールし、依存関係リストに保存します。
$ npm install express --save
現在のディレクトリ( markdown-api
)にindex.jsファイルを作成し、次のコードを追加して、Expressフレームワークが正しくインストールされているかどうかをテストします。
Const express = require('express'); var app = express(); app.get('/', function(req, res){ res.send('Hello World!'); }); app.listen(3000);
次に、URL https://localhost:3000
を参照して、テストファイルが正しく機能しているかどうかを確認します。 すべてが正常であれば、Hello Worldが表示されます!」 ブラウザで挨拶すると、MarkdownをHTMLに変換するためのベースAPIの構築に進むことができます。
ステージ2:ベースAPIの構築
APIの主な目的は、Markdown構文のテキストをHTMLに変換することです。 APIには2つのエンドポイントがあります。
-
/login
-
/convert
login
エンドポイントにより、アプリケーションは有効なリクエストを認証できますが、 convert
エンドポイントは(明らかに)マークダウンをHTMLに変換します。
以下は、2つのエンドポイントを呼び出すための基本APIコードです。 login
呼び出しは「Authenticated」文字列を返すだけですが、 convert
呼び出しはアプリケーションに送信したMarkdownコンテンツを返します。 homeメソッドは「HelloWorld!」を返すだけです。 ストリング。
const express = require("express"); const bodyParser = require('body-parser'); var app = express(); app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); app.get('/', function(req, res){ res.send('Hello World!'); }); app.post('/login', function(req, res) { res.send("Authenticated"); }, ); app.post("/convert", function(req, res, next) { console.log(req.body); if(typeof req.body.content == 'undefined' || req.body.content == null) { res.json(["error", "No data found"]); } else { res.json(["markdown", req.body.content]); } }); app.listen(3000, function() { console.log("Server running on port 3000"); });
body-parser
ミドルウェアを使用して、アプリケーションへの着信要求を簡単に解析できるようにします。 ミドルウェアは、すべての着信要求をreq.body
プロパティで利用できるようにします。 ミドルウェアを追加しなくても実行できますが、ミドルウェアを追加すると、さまざまな着信要求パラメーターの解析がはるかに簡単になります。
npmを使用するだけbody-parser
をインストールできます。
$ npm install body-parser
ダミーのスタブ関数が配置されたので、Postmanを使用して同じものをテストします。 まず、Postmanの概要から始めましょう。
郵便配達員の概要
Postmanは、ブラウザ内から、またはデスクトップアプリケーションをダウンロードすることでAPIエンドポイントを簡単に構築、変更、テストできるAPI開発ツールです(ブラウザバージョンは非推奨になりました)。 GET、POST、PUT、PATCHなどのさまざまなタイプのHTTPリクエストを作成する機能があります。 Windows、macOS、Linuxで利用できます。
Postmanのインターフェースの味は次のとおりです。
APIエンドポイントをクエリするには、次の手順を実行する必要があります。
- 上部のセクションのURLバーにクエリするURLを入力します。
- URLバーの左側にあるHTTPメソッドを選択して、リクエストを送信します。
- [送信]ボタンをクリックします。
次に、Postmanはリクエストをアプリケーションに送信し、応答を取得して下部のウィンドウに表示します。 これは、Postmanツールの使用方法に関する基本的なメカニズムです。 このアプリケーションでは、リクエストに他のパラメータも追加する必要があります。これについては、次のセクションで説明します。
Postmanを使用する
Postmanの概要を確認したので、アプリケーションでのPostmanの使用に進みましょう。
コマンドラインからmarkdown-api
アプリケーションを起動します。
$ node index.js
基本APIコードをテストするために、PostmanからアプリケーションへのAPI呼び出しを行います。 POSTメソッドを使用して、アプリケーションに変換するテキストを渡すことに注意してください。
現在、アプリケーションはMarkdown content
を受け入れて、contentPOSTパラメーターを介して変換します。 これをURLエンコード形式として渡します。 現在、アプリケーションは文字列をJSON形式で逐語的に返します。最初のフィールドは常に文字列のmarkdown
を返し、2番目のフィールドは変換されたテキストを返します。 後でMarkdown処理コードを追加すると、変換されたテキストが返されます。
ステージ3:マークダウンコンバーターの追加
アプリケーションスキャフォールドが構築されたので、MarkdownをHTMLに変換するために使用するShowdown
ライブラリを調べることができます。 Showdownは、JavaScriptで記述された双方向のMarkdownからHTMLへのコンバーターであり、MarkdownをHTMLに変換したり元に戻したりすることができます。
npmを使用してパッケージをインストールします。
$ npm install showdown
必要な対決コードをスキャフォールドに追加すると、次の結果が得られます。
const express = require("express"); const bodyParser = require('body-parser'); const showdown = require('showdown'); var app = express(); app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); converter = new showdown.Converter(); app.get('/', function(req, res){ res.send('Hello World!'); }); app.post('/login', function(req, res) { res.send("Authenticated"); }, ); app.post("/convert", function(req, res, next) { if(typeof req.body.content == 'undefined' || req.body.content == null) { res.json(["error", "No data found"]); } else { text = req.body.content; html = converter.makeHtml(text); res.json(["markdown", html]); } }); app.listen(3000, function() { console.log("Server running on port 3000"); });
以下に抽出して示すように、メインのコンバーターコードは/convert
エンドポイントにあります。 これにより、投稿したMarkdownテキストがHTMLバージョンに変換され、JSONドキュメントとして返されます。
... } else { text = req.body.content; html = converter.makeHtml(text); res.json(["markdown", html]); }
変換を行うメソッドはconverter.makeHtml(text)
です。 次の形式のsetOption
メソッドを使用して、Markdown変換のさまざまなオプションを設定できます。
converter.setOption('optionKey', 'value');
したがって、たとえば、マークアップなしで指定されたURLを自動的に挿入してリンクするオプションを設定できます。
converter.setOption('simplifiedAutoLink', 'true');
Postmanの例のように、単純な文字列( Google home https://www.google.com/
など)をアプリケーションに渡すと、 simplifiedAutoLink
が有効になっている場合、次の文字列が返されます。
<p>Google home <a href="https://www.google.com/">https://www.google.com/</a></p>
オプションがない場合、同じ結果を得るにはマークアップ情報を追加する必要があります。
Google home <https://www.google.com/>
マークダウンの処理方法を変更するための多くのオプションがあります。 完全なリストはShowdownのWebサイトにあります。
これで、単一のエンドポイントで動作するMarkdownからHTMLへのコンバーターができました。 さらに進んで、認証を追加してアプリケーションを作成しましょう。
ステージ4:パスポートを使用したAPI認証の追加
適切な認証なしでアプリケーションAPIを外部に公開すると、ユーザーは制限なしでAPIエンドポイントをクエリするようになります。 これにより、悪意のある要素がAPIを悪用する可能性があり、サーバーにモデレートされていないリクエストが発生します。 これを軽減するには、適切な認証メカニズムを追加する必要があります。
Passportパッケージを使用して、アプリケーションに認証を追加します。 以前に遭遇したbody-parser
ミドルウェアと同様に、PassportはNode.jsの認証ミドルウェアです。 Passportを使用する理由は、Passportにはさまざまな認証メカニズム(ユーザー名とパスワード、Facebook、Twitterなど)があり、ユーザーが特定のメカニズムを柔軟に選択できるようにするためです。 Passportミドルウェアは、多くのコードを変更することなく、Expressアプリケーションに簡単にドロップできます。
npmを使用してパッケージをインストールします。
$ npm install passport
また、認証には、後で説明するlocal
戦略を使用します。 だからそれもインストールしてください。
$ npm install passport-local
また、Passportで使用されるNode.js用のJWT(JSON Web Token)エンコードおよびデコードモジュールを追加する必要があります。
$ npm install jwt-simple
パスポートの戦略
Passportは、戦略の概念を使用してリクエストを認証します。 戦略は、リクエストを認証できるさまざまな方法であり、ユーザー名とパスワードの資格情報の確認、OAuth(FacebookまたはTwitter)を使用した認証、OpenIDを使用した認証などの単純なケースからさまざまです。 要求を認証する前に、アプリケーションで使用される戦略を構成する必要があります。
このアプリケーションでは、理解とコーディングが簡単なため、単純なユーザー名とパスワードの認証スキームを使用します。 現在、Passportはここで見つけることができる300以上の戦略をサポートしています。
Passportの設計は複雑に見えるかもしれませんが、コードでの実装は非常に簡単です。 これは、 /convert
エンドポイントが認証用にどのように装飾されているかを示す例です。 ご覧のとおり、メソッドに認証を追加するのは簡単です。
app.post("/convert", passport.authenticate('local',{ session: false, failWithError: true }), function(req, res, next) { // If this function gets called, authentication was successful. // Also check if no content is sent if(typeof req.body.content == 'undefined' || req.body.content == null) { res.json(["error", "No data found"]); } else { text = req.body.content; html = converter.makeHtml(text); res.json(["markdown", html]); }}, // Return a 'Unauthorized' message back if authentication failed. function(err, req, res, next) { return res.status(401).send({ success: false, message: err }) });
ここで、変換するMarkdown文字列とともに、ユーザー名とパスワードも送信する必要があります。 これは、アプリケーションのユーザー名とパスワードで確認され、確認されます。 認証にローカル戦略を使用しているため、資格情報はコード自体に保存されます。
これはセキュリティの悪夢のように聞こえるかもしれませんが、デモアプリケーションの場合はこれで十分です。 これにより、この例の認証プロセスを理解しやすくなります。 ちなみに、使用される一般的なセキュリティ方法は、環境変数にクレデンシャルを格納することです。 それでも、多くの人がこの方法に同意しないかもしれませんが、私はこれが比較的安全だと思います。
認証の完全な例を以下に示します。
const express = require("express"); const showdown = require('showdown'); const bodyParser = require('body-parser'); const passport = require('passport'); const jwt = require('jwt-simple'); const LocalStrategy = require('passport-local').Strategy; var app = express(); app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); converter = new showdown.Converter(); const ADMIN = 'admin'; const ADMIN_PASSWORD = 'smagazine'; const SECRET = 'secret#4456'; passport.use(new LocalStrategy(function(username, password, done) { if (username === ADMIN && password === ADMIN_PASSWORD) { done(null, jwt.encode({ username }, SECRET)); return; } done(null, false); })); app.get('/', function(req, res){ res.send('Hello World!'); }); app.post('/login', passport.authenticate('local',{ session: false }), function(req, res) { // If this function gets called, authentication was successful. // Send a 'Authenticated' string back. res.send("Authenticated"); }); app.post("/convert", passport.authenticate('local',{ session: false, failWithError: true }), function(req, res, next) { // If this function gets called, authentication was successful. // Also check if no content is sent if(typeof req.body.content == 'undefined' || req.body.content == null) { res.json(["error", "No data found"]); } else { text = req.body.content; html = converter.makeHtml(text); res.json(["markdown", html]); }}, // Return a 'Unauthorized' message back if authentication failed. function(err, req, res, next) { return res.status(401).send({ success: false, message: err }) }); app.listen(3000, function() { console.log("Server running on port 3000"); });
認証が追加された変換を示すPostmanセッションを以下に示します。
ここで、Markdown構文から適切なHTML変換された文字列を取得したことがわかります。 Markdownの1行の変換のみを要求しましたが、APIはより多くのテキストを変換できます。
これで、Node.jsとExpressを使用してAPIエンドポイントを構築するための簡単な取り組みは終わりです。 APIの構築は複雑なトピックであり、APIの構築中に注意する必要のある微妙なニュアンスがあります。残念ながら、ここで説明する時間はありませんが、今後の記事で取り上げる予定です。
別のアプリケーションからAPIにアクセスする
APIを作成したので、APIにアクセスする方法を示す小さなNode.jsスクリプトを作成できます。 この例では、HTTP request
を作成する簡単な方法を提供するrequestnpmパッケージをインストールする必要があります。 (おそらく、これはすでにインストールされています。)
$ npm install request --save
APIにリクエストを送信し、レスポンスを取得するためのサンプルコードを以下に示します。 ご覧のとおり、 request
パッケージは問題を大幅に簡素化します。 変換されるマークダウンは、 textToConvert
変数にあります。
次のスクリプトを実行する前に、前に作成したAPIアプリケーションがすでに実行されていることを確認してください。 別のコマンドウィンドウで次のスクリプトを実行します。
注: textToConvert
変数の複数のJavaScript行にまたがる(back-tick)
記号を使用しています。 これは一重引用符ではありません。
var Request = require("request"); // Start of markdown var textToConvert = `Heading ======= ## Sub-heading Paragraphs are separated by a blank line. Two spaces at the end of a line produces a line break. Text attributes _italic_, **bold**, 'monospace'. A [link](https://example.com). Horizontal rule:`; // End of markdown Request.post({ "headers": { "content-type": "application/json" }, "url": "https://localhost:3000/convert", "body": JSON.stringify({ "content": textToConvert, "username": "admin", "password": "smagazine" }) }, function(error, response, body){ // If we got any connection error, bail out. if(error) { return console.log(error); } // Else display the converted text console.dir(JSON.parse(body)); });
APIにPOSTリクエストを行うと、変換するマークダウンテキストとクレデンシャルが提供されます。 間違ったクレデンシャルを入力すると、エラーメッセージが表示されます。
{ success: false, message: { name: 'AuthenticationError', message: 'Unauthorized', status: 401 } }
正しく承認されたリクエストの場合、上記のサンプルMarkdownは次のように変換されます。
[ 'markdown', `<h1>Heading</h1> <h2>Sub-heading</h2> <p>Paragraphs are separated by a blank line.</p> <p>Two spaces at the end of a line<br /> produces a line break.</p> <p>Text attributes <em>italic</em>, <strong>bold</strong>, 'monospace'. A <a href="https://example.com">link</a>. Horizontal rule:</p>` ]
ここではマークダウンをハードコーディングしていますが、テキストはファイル、Webフォームなど、他のさまざまなソースから取得できます。 リクエストプロセスは同じままです。
application/json
コンテンツタイプとしてリクエストを送信していることに注意してください。 jsonを使用して本文をエンコードする必要があるため、 JSON.stringify
関数を呼び出します。 ご覧のとおり、テストまたはAPIアプリケーションの例はごくわずかです。
結論
この記事では、Node、js、およびExpressフレームワークを使用してAPIエンドポイントを構築する方法を学習することを目的としたチュートリアルに着手しました。 目的のないダミーアプリケーションを構築するのではなく、Markdown構文をHTMLに変換するAPIを作成することにしました。これは、有用なコンテキストでアンカーまたは学習します。 その過程で、APIエンドポイントに認証を追加し、Postmanを使用してアプリケーションエンドポイントをテストする方法も確認しました。