chore(i18n,learn): processed translations (#44851)
This commit is contained in:
@ -0,0 +1,79 @@
|
||||
---
|
||||
id: 587d7fb1367417b2b2512bf4
|
||||
title: ミドルウェアをチェーンしてタイムサーバーを作成する
|
||||
challengeType: 2
|
||||
forumTopicId: 301510
|
||||
dashedName: chain-middleware-to-create-a-time-server
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
`app.METHOD(path, middlewareFunction)` を使用して、ミドルウェアを特定のルートにマウントすることができます。 ミドルウェアをルート定義の中でチェーンすることもできます。
|
||||
|
||||
以下の例を見てください。
|
||||
|
||||
```js
|
||||
app.get('/user', function(req, res, next) {
|
||||
req.user = getTheUserSync(); // Hypothetical synchronous operation
|
||||
next();
|
||||
}, function(req, res) {
|
||||
res.send(req.user);
|
||||
});
|
||||
```
|
||||
|
||||
このアプローチは、サーバー操作を小さいユニットに分割するのに便利です。 これにより、アプリの構造が整理され、異なる場所でコードを再利用できるようになります。 このアプローチは、データに対して何らかの検証を実行する場合にも使用できます。 ミドルウェア スタックの各ポイントで、現在のチェーンの実行をブロックし、エラーを処理するために特別に設計された関数へ制御を渡すことができます。 または、特別なケースを処理するために、次にマッチするルートへ制御を渡すこともできます。 詳しくは「高度な Express」セクションで説明します。
|
||||
|
||||
# --instructions--
|
||||
|
||||
ルート `app.get('/now', ...)` で、ミドルウェア関数と最後のハンドラーをチェーンします。 ミドルウェア関数では、リクエストオブジェクトの `req.time` キーに現在時刻を追加する必要があります。 `new Date().toString()` を使用できます。 ハンドラーでは、JSON オブジェクトで応答し、構造体 `{time: req.time}` を受け取ってください。
|
||||
|
||||
** 注意:** ミドルウェアをチェーンしない場合、テストには合格しません。 関数を別の場所にマウントした場合、出力結果が正しくてもテストは不合格となります。
|
||||
|
||||
# --hints--
|
||||
|
||||
/now エンドポイントで、ミドルウェアをマウントしている必要があります。
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.get(getUserInput('url') + '/_api/chain-middleware-time').then(
|
||||
(data) => {
|
||||
assert.equal(
|
||||
data.stackLength,
|
||||
2,
|
||||
'"/now" route has no mounted middleware'
|
||||
);
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
/now エンドポイントで、今から +/- 20 秒の時間を返す必要があります。
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.get(getUserInput('url') + '/_api/chain-middleware-time').then(
|
||||
(data) => {
|
||||
var now = new Date();
|
||||
assert.isAtMost(
|
||||
Math.abs(new Date(data.time) - now),
|
||||
20000,
|
||||
'the returned time is not between +- 20 secs from now'
|
||||
);
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
@ -0,0 +1,78 @@
|
||||
---
|
||||
id: 587d7fb2367417b2b2512bf8
|
||||
title: POST リクエストからデータを取得する
|
||||
challengeType: 2
|
||||
forumTopicId: 301511
|
||||
dashedName: get-data-from-post-requests
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
パス `/name` で POST ハンドラーをマウントしてください。 これは前回と同じパスです。 html のフロントページにフォームが用意されています。 このフォームは、演習 10 (クエリ文字列) と同じデータを送信します。 ボディパーサーが正しく設定されている場合は、`req.body` オブジェクトにパラメーターが見つかります。 次は通常のライブラリの例です。
|
||||
|
||||
<blockquote>route: POST '/library'<br>urlencoded_body: userId=546&bookId=6754 <br>req.body: {userId: '546', bookId: '6754'}</blockquote>
|
||||
|
||||
前回と同じ JSON オブジェクト `{name: 'firstname lastname'}` で応答してください。 アプリのフロントページに提供されている html フォームを使用してエンドポイントが動作するかどうかをテストしてください。
|
||||
|
||||
ヒント: GET と POST 以外にもいくつかの http メソッドがあります。 慣例として、http 動詞とサーバ上で実行する操作には対応関係があります。 従来の対応関係は以下のようになっています。
|
||||
|
||||
POST (場合によっては PUT) - リクエストと共に送信された情報を使用して新しいリソースを作成する。
|
||||
|
||||
GET - 既存のリソースを変更せずに読み取る。
|
||||
|
||||
PUT または PATCH (場合によっては POST) - 送信されたデータを使用してリソースを更新する。
|
||||
|
||||
DELETE => リソースを削除する。
|
||||
|
||||
他にもサーバーとの接続のやり取りに使用するメソッドがいくつかあります。 GET を除いて、上記のメソッドはすべてペイロードを持つことができます (つまり、データをリクエストボディに保存できます)。 ボディ解析ミドルウェアでもこれらのメソッドを使用できます。
|
||||
|
||||
# --hints--
|
||||
|
||||
テスト 1: API エンドポイントは、正しい名前で応答する必要があります。
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.post(getUserInput('url') + '/name', { first: 'Mick', last: 'Jagger' }).then(
|
||||
(data) => {
|
||||
assert.equal(
|
||||
data.name,
|
||||
'Mick Jagger',
|
||||
'Test 1: "POST /name" route does not behave as expected'
|
||||
);
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
テスト 2: API エンドポイントは、正しい名前で応答する必要があります。
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.post(getUserInput('url') + '/name', {
|
||||
first: 'Keith',
|
||||
last: 'Richards'
|
||||
}).then(
|
||||
(data) => {
|
||||
assert.equal(
|
||||
data.name,
|
||||
'Keith Richards',
|
||||
'Test 2: "POST /name" route does not behave as expected'
|
||||
);
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
@ -0,0 +1,67 @@
|
||||
---
|
||||
id: 587d7fb2367417b2b2512bf6
|
||||
title: クライアントからクエリパラメーター入力を取得する
|
||||
challengeType: 2
|
||||
forumTopicId: 301512
|
||||
dashedName: get-query-parameter-input-from-the-client
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
クライアントから入力を取得するもう一つの一般的な方法として、クエリ文字列を使用してルートパスの後にデータをエンコードすることができます。 クエリ文字列は、疑問符 (?) で区切られ、field=value のペアを含みます。 各ペアはアンパサンド (&) で区切られます。 Express では、クエリ文字列のデータを解析し、`req.query` オブジェクトを設定することができます。 パーセント (%) などのいくつかの文字は URL に含めることができないので、送信する前に別の形式にエンコードする必要があります。 JavaScript の API を使用する場合は、そうした文字をエンコード/デコードするために特定のメソッドを使用できます。
|
||||
|
||||
<blockquote>route_path: '/library'<br>actual_request_URL: '/library?userId=546&bookId=6754' <br>req.query: {userId: '546', bookId: '6754'}</blockquote>
|
||||
|
||||
# --instructions--
|
||||
|
||||
API エンドポイントを構築し、`GET /name` でマウントしてください。 JSON ドキュメントで応答し、構造体 `{ name: 'firstname lastname'}` を受け取ってください。 ファーストネームおよびラストネームのパラメーターは、`?first=firstname&last=lastname` などのクエリ文字列にエンコードする必要があります。
|
||||
|
||||
** 注: ** 以下の演習では、同じ `/name` ルートパスで、POST リクエストからデータを受け取ります。 必要に応じて、メソッド `app.route(path).get(handler).post(handler)` を使用できます。 このシンタックスにより、同じパスルート上で異なる動詞ハンドラーをチェーンすることができます。 入力する文字数が少しだけ減り、コードがわかりやすくなります。
|
||||
|
||||
# --hints--
|
||||
|
||||
テスト 1: API エンドポイントは、正しい名前で応答する必要があります。
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.get(getUserInput('url') + '/name?first=Mick&last=Jagger').then(
|
||||
(data) => {
|
||||
assert.equal(
|
||||
data.name,
|
||||
'Mick Jagger',
|
||||
'Test 1: "GET /name" route does not behave as expected'
|
||||
);
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
テスト 2: API エンドポイントは、正しい名前で応答する必要があります。
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.get(getUserInput('url') + '/name?last=Richards&first=Keith').then(
|
||||
(data) => {
|
||||
assert.equal(
|
||||
data.name,
|
||||
'Keith Richards',
|
||||
'Test 2: "GET /name" route does not behave as expected'
|
||||
);
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
@ -0,0 +1,65 @@
|
||||
---
|
||||
id: 587d7fb2367417b2b2512bf5
|
||||
title: クライアントからルートパラメータ入力を取得する
|
||||
challengeType: 2
|
||||
forumTopicId: 301513
|
||||
dashedName: get-route-parameter-input-from-the-client
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
API を構築する際は、私たちが作成するサービスから何を得たいのかをユーザーに伝えてもらうようにする必要があります。 たとえばクライアントが、データベースに保存されているユーザーに関する情報を要求している場合、どのユーザーに興味があるのかをクライアントから伝えてもらうための手段が必要になります。 そのための方法の一つとして、ルートパラメーターの使用があります。 ルートパラメーターは名前の付いた URL のセグメントであり、スラッシュ (/) で区切られます。 各セグメントは、URL のうちその位置と一致する部分の値を取得します。 取得した値は、`req.params` オブジェクトに保存されます。
|
||||
|
||||
<blockquote>route_path: '/user/:userId/book/:bookId'<br>actual_request_URL: '/user/546/book/6754' <br>req.params: {userId: '546', bookId: '6754'}</blockquote>
|
||||
|
||||
# --instructions--
|
||||
|
||||
エコーサーバーを構築し、ルート `GET /:word/echo` にマウントしてください。 JSON オブジェクトで応答し、構造体 `{echo: word}` を受け取ってください。 繰り返すワードは `req.params.word` で見つけることができます。 たとえば、`your-app-rootpath/freecodecamp/echo` のように、一致するルートにアクセスして、ブラウザーのアドレスバーからルートをテストすることができます。
|
||||
|
||||
# --hints--
|
||||
|
||||
テスト 1: エコーサーバーは、ワードを正しく繰り返す必要があります。
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.get(getUserInput('url') + '/eChOtEsT/echo').then(
|
||||
(data) => {
|
||||
assert.equal(
|
||||
data.echo,
|
||||
'eChOtEsT',
|
||||
'Test 1: the echo server is not working as expected'
|
||||
);
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
テスト 2: エコーサーバーは、ワードを正しく繰り返す必要があります。
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.get(getUserInput('url') + '/ech0-t3st/echo').then(
|
||||
(data) => {
|
||||
assert.equal(
|
||||
data.echo,
|
||||
'ech0-t3st',
|
||||
'Test 2: the echo server is not working as expected'
|
||||
);
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
@ -0,0 +1,57 @@
|
||||
---
|
||||
id: 587d7fb1367417b2b2512bf3
|
||||
title: ルートレベルのリクエスト ロガー ミドルウェアを実装する
|
||||
challengeType: 2
|
||||
forumTopicId: 301514
|
||||
dashedName: implement-a-root-level-request-logger-middleware
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
前に `express.static()` ミドルウェア関数について説明しました。 ここでは、ミドルウェアとはどのようなものなのか、もっと詳しく説明しましょう。 ミドルウェア関数は 3 つの引数を取る関数です。それらは、リクエストオブジェクト、レスポンスオブジェクト、そして、アプリケーションのリクエストレスポンスサイクルにおける次の関数です。 これらの関数は、アプリケーションに副次的な効果を与えるコードを実行し、通常はリクエストオブジェクトもしくはレスポンスオブジェクトへ情報を追加します。 また、条件が満たされたときにレスポンスを送信して、サイクルを終了することもできます。 終了時にレスポンスを送信しない場合は、スタック内で次の関数の実行を開始します。 これにより、3 番目の引数 `next()` が呼び出されます。
|
||||
|
||||
以下の例を見てください。
|
||||
|
||||
```js
|
||||
function(req, res, next) {
|
||||
console.log("I'm a middleware...");
|
||||
next();
|
||||
}
|
||||
```
|
||||
|
||||
ルートにこの関数をマウントしたとしましょう。 リクエストがルートと一致すると、「I'm a middleware…」という文字列が表示され、スタック内で次の関数が実行されます。 この演習では、ルートレベルのミドルウェアを構築します。 チャレンジ 4 で説明したように、ミドルウェア関数をルートレベルでマウントするには、 `app.use(<mware-function>)` メソッドを使用できます。 この場合、関数はすべてのリクエストに対して実行されますが、より具体的な条件を設定することもできます。 たとえば、POST リクエストに対してのみ関数を実行したい場合は、 `app.post(<mware-function>)` を使用できます。 すべての HTTP 動詞 (GET、DELETE、PUT、 … ) について、類似したメソッドがあります。
|
||||
|
||||
# --instructions--
|
||||
|
||||
シンプルなロガーを構築してください。 リクエストごとに、`method path - ip` という形式の文字列をコンソールへ記録する必要があります。 たとえば `GET /json - ::ffff:127.0.0.1` などとします。 `method` と `path` の間に空白を入れ、`path` と `ip` を区切るダッシュの両側を空白で囲むことに注意してください。 `req.method`、`req.path` および `req.ip` を使用して、リクエストメソッド (http 動詞)、相対ルートパスおよびリクエストオブジェクトの発信者 ip を取得できます。 処理を終えたら忘れずに `next()` を呼び出してください。そうしないとサーバーがずっと無応答になります。 必ず 「Logs」を開き、リクエストが届いたときにどうなるか確認してください。
|
||||
|
||||
** 注: ** Express では、関数はコード内に出現する順序で評価されます。 この動作はミドルウェアにも適用されます。 すべてのルートで動作させたい場合は、それらの前でマウントする必要があります。
|
||||
|
||||
# --hints--
|
||||
|
||||
ルートレベルのロガーミドルウェアをアクティブにする必要があります。
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.get(getUserInput('url') + '/_api/root-middleware-logger').then(
|
||||
(data) => {
|
||||
assert.isTrue(
|
||||
data.passed,
|
||||
'root-level logger is not working as expected'
|
||||
);
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
@ -0,0 +1,53 @@
|
||||
---
|
||||
id: 587d7fb0367417b2b2512bed
|
||||
title: ノードコンソールを確認する
|
||||
challengeType: 2
|
||||
forumTopicId: 301515
|
||||
dashedName: meet-the-node-console
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
チャレンジに取り組むにあたり、以下の方法のうち 1 つを用いてコードを記述します。
|
||||
|
||||
- [GitHub レポジトリ](https://github.com/freeCodeCamp/boilerplate-express/)をクローンし、ローカル環境でチャレンジを完了させる。
|
||||
- [Replit 始動プロジェクト](https://replit.com/github/freeCodeCamp/boilerplate-express)を使用してチャレンジを完了させる。
|
||||
- 使い慣れたサイトビルダーを使用してプロジェクトを完了させる。 必ず GitHub リポジトリのすべてのファイルを取り込む。
|
||||
|
||||
完了したら、プロジェクトの動作デモをどこか公開の場にホストしてください。 そして、`Solution Link` フィールドでデモへの URL を送信してください。
|
||||
|
||||
開発プロセスでは、コード内で何が起きているかを確認できるようにすることが重要です。
|
||||
|
||||
Node は単なる JavaScript 環境にすぎません。 クライアントサイド JavaScript と同様に、コンソールを使用して有用なデバッグ情報を表示できます。 ローカルマシンでは、ターミナルでコンソール出力を確認できます。 Replit では、デフォルトで右側のペインにターミナルが開きます。
|
||||
|
||||
チャレンジの作業中はターミナルを開いたままにしておくことをお勧めします。 ターミナルの出力を読み取ることで、発生する可能性のあるエラーを確認することができます。
|
||||
|
||||
# --instructions--
|
||||
|
||||
`myApp.js` ファイルを変更して、コンソールログに「Hello World」と出力してください。
|
||||
|
||||
# --hints--
|
||||
|
||||
`"Hello World"` がコンソールに表示されます。
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.get(getUserInput('url') + '/_api/hello-console').then(
|
||||
(data) => {
|
||||
assert.isTrue(data.passed, '"Hello World" is not in the server console');
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
@ -0,0 +1,51 @@
|
||||
---
|
||||
id: 587d7fb0367417b2b2512bef
|
||||
title: HTML ファイルを提供する
|
||||
challengeType: 2
|
||||
forumTopicId: 301516
|
||||
dashedName: serve-an-html-file
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
`res.sendFile(path)` メソッドを使用して、ファイルでリクエストに応答することができます。 メソッドは `app.get('/', ...)` ルートハンドラーの中に記述できます。 このメソッドは、送信したいファイルの処理方法をブラウザーに指示するための適切なヘッダーを、そのファイルタイプに応じて設定します。 そして、ファイルを読み取り、送信します。 このメソッドには絶対ファイルパスが必要です。 以下のようなパスを計算するために、Node のグローバル変数 `__dirname` を使用することを推奨します。
|
||||
|
||||
```js
|
||||
absolutePath = __dirname + relativePath/file.ext
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
GET リクエストへのレスポンスとして、`/views/index.html` ファイルを `/` パスへ送信します。 動作可能なアプリを表示すると、大きな HTML 見出し (および、あとで使用するフォーム) が、スタイルが適用されていない状態で表示されることが確認できるはずです。
|
||||
|
||||
**注:** 前回のチャレンジのソリューションを編集するか、新しいチャレンジを作成できます。 新しいソリューションを作成する場合、Express ではルートが上から下に向かって評価され、最初に一致したルートのハンドラーが実行されることに注意してください。 前のソリューションをコメントアウトする必要があります。そうしないとサーバーは文字列で応答し続けます。
|
||||
|
||||
# --hints--
|
||||
|
||||
アプリからファイル views/index.html を提供する必要があります。
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.get(getUserInput('url')).then(
|
||||
(data) => {
|
||||
assert.match(
|
||||
data,
|
||||
/<h1>.*<\/h1>/,
|
||||
'Your app does not serve the expected HTML'
|
||||
);
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
@ -0,0 +1,47 @@
|
||||
---
|
||||
id: 587d7fb1367417b2b2512bf1
|
||||
title: 特定のルート上で JSON を提供する
|
||||
challengeType: 2
|
||||
forumTopicId: 301517
|
||||
dashedName: serve-json-on-a-specific-route
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
HTML サーバーは HTML を提供しますが、API はデータを提供します。 <dfn>REST</dfn> (REpresentational State Transfer) API では、クライアントがサーバーの詳細を知らなくても、簡単な方法でデータ交換ができます。 クライアントで知る必要があるのは、リソースのある場所 (URL) と、そこで実行したいアクション (動詞) だけです。 GET 動詞は、情報を取得するだけで何も変更を加えない場合に使用します。 最近では、ウェブでの情報の操作に使用するデータ形式として JSON が好まれています。 簡単に言えば、JSON は JavaScript オブジェクトを文字列として表現する便利な手段であり、簡単に送信することができます。
|
||||
|
||||
シンプルな API として、パス `/json` で JSON で応答するルートを作成してみましょう。 いつものように `app.get()` メソッドを使用できます。 ルートハンドラートの中で、メソッド `res.json()` を使用し、オブジェクトを引数として渡します。 このメソッドは、リクエスト-レスポンス ループを閉じ、データを返します。 バックグラウンドでは、有効な JavaScript オブジェクトを文字列に変換します。そして、適切なヘッダーを設定して、JSON を提供しようとしていることをブラウザーに伝え、データを返します。 有効なオブジェクトには通常の構造体 `{key: data}` があります。 `data` は、数値、文字列、ネストされたオブジェクトまたは配列です。 `data` はまた、変数または関数呼び出しの結果になることもあり、その場合は文字列に変換される前に評価されます。
|
||||
|
||||
# --instructions--
|
||||
|
||||
オブジェクト `{"message": "Hello json"}` を JSON 形式のレスポンスとして、`/json` ルートへの GET リクエストに提供します。 ブラウザーから `your-app-url/json` にアクセスすると、画面にメッセージが表示されます。
|
||||
|
||||
# --hints--
|
||||
|
||||
エンドポイント `/json` は json オブジェクト `{"message": "Hello json"}` を提供する必要があります。
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.get(getUserInput('url') + '/json').then(
|
||||
(data) => {
|
||||
assert.equal(
|
||||
data.message,
|
||||
'Hello json',
|
||||
"The '/json' endpoint does not serve the right data"
|
||||
);
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
@ -0,0 +1,51 @@
|
||||
---
|
||||
id: 587d7fb0367417b2b2512bf0
|
||||
title: 静的アセットを提供する
|
||||
challengeType: 2
|
||||
forumTopicId: 301518
|
||||
dashedName: serve-static-assets
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
HTML サーバーには通常、ユーザーがアクセスできるディレクトリが 1 つ以上あります。 それらのディレクトリには、アプリに必要な静的アセット (スタイルシート、スクリプト、画像) を置くことができます。
|
||||
|
||||
Express では、ミドルウェア `express.static(path)` を使用してこの機能を実現できます。ここで、`path` パラメーターはアセットのあるフォルダーの絶対パスです。
|
||||
|
||||
ミドルウェアのことが分からなくても心配はいりません。後で詳しく説明します。 基本的に、ミドルウェアとは、ルートハンドラーに割り込んで何らかの情報を追加する関数です。 ミドルウェアはメソッド `app.use(path, middlewareFunction)` を使用してマウントする必要があります。 最初の `path` 引数は任意です。 これを渡さない場合は、すべてのリクエストに対してミドルウェアが実行されます。
|
||||
|
||||
# --instructions--
|
||||
|
||||
`app.use()` を使用して、`express.static()` ミドルウェアをパス `/public` にマウントしてください。 アセットフォルダーへの絶対パスは `__dirname + /public` です。
|
||||
|
||||
これで、アプリが CSS スタイルシートを提供できるようになります。 `/public/style.css` ファイルは、プロジェクト ボイラープレートの `/views/index.html` で参照されることに注意してください。 これで、フロントページの見栄えが少し良くなっているはずです!
|
||||
|
||||
# --hints--
|
||||
|
||||
アプリは、`/public` ディレクトリから `/public` パスにアセットファイルを提供する必要があります。
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.get(getUserInput('url') + '/public/style.css').then(
|
||||
(data) => {
|
||||
assert.match(
|
||||
data,
|
||||
/body\s*\{[^\}]*\}/,
|
||||
'Your app does not serve static assets'
|
||||
);
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
@ -0,0 +1,57 @@
|
||||
---
|
||||
id: 587d7fb0367417b2b2512bee
|
||||
title: 作業用の Express サーバーを起動する
|
||||
challengeType: 2
|
||||
forumTopicId: 301519
|
||||
dashedName: start-a-working-express-server
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
ファイル `myApp.js` の最初の 2 行を見ると、Express アプリオブジェクトを簡単に作成できることがわかります。 このオブジェクトにはいくつかのメソッドがあり、チャレンジでそれらの多くを学ぶことになります。 基本的なメソッドの一つが、`app.listen(port)` です。 このメソッドは、指定されたポートをリッスンするようにサーバーへ指示し、サーバーを実行中の状態にします。 テスト目的のため、アプリをバックグラウンドで実行する必要があります。そのため、このメソッドを `server.js` ファイルに追加しました。
|
||||
|
||||
サーバーから最初の文字列を提供してみましょう! Express では、ルートは `app.METHOD(PATH, HANDLER)` という構造をとります。 METHOD は、小文字の http メソッドです。 PATH は、サーバー上の相対パスです (文字列、または正規表現でもかまいません) 。 HANDLER は、ルートが一致したときに Express が呼び出す関数です。 ハンドラーは `function(req, res) {...}` という形式をとります。req はリクエストオブジェクトで、res はレスポンスオブジェクトです。 たとえば、下記のハンドラー
|
||||
|
||||
```js
|
||||
function(req, res) {
|
||||
res.send('Response String');
|
||||
}
|
||||
```
|
||||
|
||||
は、文字列「Response String」を提供します。
|
||||
|
||||
# --instructions--
|
||||
|
||||
`app.get()` メソッドを使用して、`/` (root) パスに一致する GET リクエストに対して文字列「Hello Express」を提供してください。 ログを見てコードが動作することを確認し、Replit を使用している場合はプレビューで結果を確認してください。
|
||||
|
||||
** 注: ** レッスンのコードはすべて、あらかじめ用意されている数行のコードの間に追加する必要があります。
|
||||
|
||||
# --hints--
|
||||
|
||||
アプリは、「Hello Express」という文字列を提供する必要があります。
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.get(getUserInput('url')).then(
|
||||
(data) => {
|
||||
assert.equal(
|
||||
data,
|
||||
'Hello Express',
|
||||
'Your app does not serve the text "Hello Express"'
|
||||
);
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
@ -0,0 +1,63 @@
|
||||
---
|
||||
id: 587d7fb2367417b2b2512bf7
|
||||
title: POST リクエストを解析するためにボディパーサーを使用する
|
||||
challengeType: 2
|
||||
forumTopicId: 301520
|
||||
dashedName: use-body-parser-to-parse-post-requests
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
GET のほかにもう一つ一般的な HTTP 動詞があります。それは、POST です。 POST は、HTML フォームを使用してクライアントデータを送信するために使用するデフォルトのメソッドです。 REST の慣例では、POST は、データベースに新しいアイテム (新規ユーザー、または新しいブログ投稿) を作成するためのデータを送信する場合に使用します。 このプロジェクトにはデータベースはありませんが、ひとまず POST リクエストの処理方法について説明します。
|
||||
|
||||
このようなリクエストでは、データは URL には表示されず、リクエストボディに隠されています。 ボディは HTTP リクエストの一部であり、ペイロードとも呼ばれます。 URL にデータが表示されていなくても、データが非公開であるとは限りません。 その理由を理解するため、HTTP POST リクエストの処理前の内容を見てみましょう。
|
||||
|
||||
```http
|
||||
POST /path/subpath HTTP/1.0
|
||||
From: john@example.com
|
||||
User-Agent: someBrowser/1.0
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Content-Length: 20
|
||||
|
||||
name=John+Doe&age=25
|
||||
```
|
||||
|
||||
ご覧のように、ボディはクエリ文字列のようにエンコードされています。 これは、HTML のフォームで使用されるデフォルトの形式です。 Ajax では、JSON を使用してもっと複雑な構造のデータを処理することもできます。 また、multipart/form-data という別のエンコーディングタイプもあります。 これは、バイナリファイルをアップロードする場合に使用します。 この演習では、URL エンコードされたボディを使用します。 POST リクエストからのデータを解析するには、`body-parser` パッケージをインストールする必要があります。 このパッケージでは、さまざまな形式でデータをデコードできる一連のミドルウェアを使用できます。
|
||||
|
||||
# --instructions--
|
||||
|
||||
`package.json` に `body-parser` モジュールをインストールしてください。 次に、ファイルの先頭でモジュールを `require` 宣言してください。 そして、`bodyParser` という名前の変数に保存してください。 URL エンコードされたデータを処理するミドルウェアは、`bodyParser.urlencoded({extended: false})` によって返されます。 前のメソッド呼び出しで返された関数を `app.use()` に渡してください。 いつものように、ミドルウェアはそれに依存するすべてのルートよりも前にマウントする必要があります。
|
||||
|
||||
**注:** `extended` は、解析を使用する必要があるかどうかを `body-parser` に伝える設定オプションです。 `extended=false` の場合は、従来のエンコーディング `querystring` ライブラリを使用します。 `extended=true` の場合は、解析に `qs` ライブラリを使用します。
|
||||
|
||||
`extended=false` を使用する場合、値は文字列または配列のみとなります。 `querystring` を使用する場合に返されるオブジェクトは、デフォルトの JavaScript `Object` のプロトタイプを継承しません。つまり、`hasOwnProperty` や `toString` などの関数は利用できなくなります。 extended が有効な場合は、データの柔軟性が高まりますが、その点では JSON のほうが優れています。
|
||||
|
||||
# --hints--
|
||||
|
||||
「body-parser」ミドルウェアをマウントする必要があります。
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.get(getUserInput('url') + '/_api/add-body-parser').then(
|
||||
(data) => {
|
||||
assert.isAbove(
|
||||
data.mountedAt,
|
||||
0,
|
||||
'"body-parser" is not mounted correctly'
|
||||
);
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
@ -0,0 +1,54 @@
|
||||
---
|
||||
id: 587d7fb1367417b2b2512bf2
|
||||
title: .env ファイルを使用する
|
||||
challengeType: 2
|
||||
forumTopicId: 301521
|
||||
dashedName: use-the--env-file
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
`.env` ファイルは、アプリケーションに環境変数を渡すために使用される隠しファイルです。 これは非公開ファイルであり、あなた以外誰もアクセスできません。 プライベートまたは非公開にしたいデータを保存する場合に使用することができます。 たとえば、外部サービスの API キーやデータベースの URI を保存できます。 また、設定オプションを保存する場合にも使用できます。 設定オプションを設定することで、コードを書き換えずにアプリの動作を変更できます。
|
||||
|
||||
環境変数にはアプリから `process.env.VAR_NAME` としてアクセスできます。 `process.env` オブジェクトは、グローバルの Node オブジェクトであり、変数は文字列として渡されます。 慣例により、変数名はすべて大文字で、単語はアンダースコアで区切られます。 `.env` はシェルファイルなので、名前や値を引用符で囲む必要はありません。 また、変数に値を割り当てる場合、等号記号の両側に空白を付けることはできず、`VAR_NAME=value` のようにする必要があります。 通常は、それぞれの変数定義を別々の行に記述します。
|
||||
|
||||
# --instructions--
|
||||
|
||||
環境変数を設定オプションとして追加しましょう。
|
||||
|
||||
プロジェクトディレクトリのルートに `.env` ファイルを作成し、変数 `MESSAGE_STYLE=uppercase` を保存してください。
|
||||
|
||||
次に、前回のチャレンジで作成した `/json` GET ルートハンドラーで、`process.env.MESSAGE_STYLE` が `uppercase` に等しい場合に、レスポンスオブジェクトのメッセージを大文字に変換してください。 レスポンスオブジェクトは、 `MESSAGE_STYLE` の値に応じて、`{"message": "Hello json"}` または `{"message": "HELLO JSON"}` のいずれかにする必要があります。
|
||||
|
||||
** 注: ** Replit を使用している場合は、 `.env` ファイルを作成することはできません。 代わりに、組み込みの <dfn>SECRETS</dfn> タブを使用して変数を追加してください。
|
||||
|
||||
ローカル環境で作業している場合は、`dotenv` パッケージが必要です。 このパッケージにより、環境変数が `.env` ファイルから `process.env` に読み込まれます。 `npm install dotenv` でインストールしてください。 次に、 `myApp.js` ファイルの先頭で、`require('dotenv').config()` を使用して変数をインポートして読み込んでください。
|
||||
|
||||
# --hints--
|
||||
|
||||
エンドポイント `/json` のレスポンスを、環境変数 `MESSAGE_STYLE` に従って変更する必要があります。
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.get(getUserInput('url') + '/_api/use-env-vars').then(
|
||||
(data) => {
|
||||
assert.isTrue(
|
||||
data.passed,
|
||||
'The response of "/json" does not change according to MESSAGE_STYLE'
|
||||
);
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
Reference in New Issue
Block a user