N予備校 プログラミングコース 第31回
あなたは2019年の目標って立てましたか?
どんな目標を立てたか覚えていますか?
私は2018年末に2019年の目標を立てました。
その一つにプログラミングを学び仕事として使えるようにすることをあげました。
そして、思い立ったが吉日と「N予備校のプログラミングコース」を申し込みました。
そして受講と同時に自身の振替と、これから始めようと考えている人の参考になればとブログを書き始めました。
今回ブログの移設にともない、再度そのブログを読み返しながら、今思うことを加えて記載していきたいと思います。
また私が受講したのは【2018年度】で、現在公開されている【2019年度】との違いについても書いていきたいと思います。
このブログは、初心者が学びながら書いているため、間違っている場合があります。
分かり次第修正していくつもりです。
そのあたりも含め楽しんでいただければと思います。
最後に進めていてわからなかったところや気になったところをまとめています。
プログラミング入門 webアプリコース 第31回
前回は、この章の目的でもある秘密の匿名掲示板作成の要件とページ設計とモジュール設計を行いました。今回以降では、それぞれの要件に対するプログラムを実装していきます。まずは、投稿機能を実装します。
- 今回の内容まとめ(第3章 20)
・投稿機能の実装
- 今回の目標
投稿機能を実装する
- 今回新しく扱っているコマンド等
・textarea
投稿機能の実装
作成する秘密の匿名掲示板の要件がいかになります。
- 秘密の掲示板の要件
① 認証ができる
② 認証した人だけが投稿内容を閲覧できる
③ 認証した人だけが投稿できる
④ 自身の投稿内容を削除できる
⑤ 管理人機能
管理人の投稿だとわかる
管理人は全ての投稿を削除できる
管理人はどのアカウントの投稿かわかる
⑥ 匿名であるけれども同じユーザーであることを認識でき、一人で複数人が書き込んでいるような振る舞いが簡単にはできないようにできる
今回は、要件一つである「投稿できる」機能を実装します。
投稿に関するURI設計は以下の2つになります。
- 投稿一覧表示処理(/posts):GET
- 投稿とリダイレクト処理( /posts):POST
2つともパスに/postsが設定されています。
これを実行するために、必要になるのが次のモジュールです。
- /posts のリクエストを処理する
- リクエスト処理を行うハンドラに振り分ける
投稿された内容の書き出し(/postsのリクエスト処理)
/posts へのリクエストを処理するモジュール(ファイル名○○)を設計します。
投稿された内容をログに書き出し、その後投稿フォームにリダイレクトします。
1 function handle(req, res) {
2 switch (req.method) {
3 case ‘GET’:
4 res.writeHead(200, {
5 ’Content-Type’: ‘text/html; charset=utf-8’
6 });
7 res.end(pug.renderFile(‘△△’));
8 break;
9 case ‘POST’:
10 let body =[];
11 req.on(‘data’, (chunk) => {
12 body.push(chunk);
13 }).on(‘end’, () => {
14 body = Buffer.concat(body).toString();
15 const decoded = decodeURIComponent(body);
16 const content = decoded.split(‘content=’);
17 console.info(‘投稿されました: ‘ + content);
18 handleRedirectPosts(req, res);
19 });
20 break;
21 default:
22 break;
23 }
24 }
25 function handleRedirectPosts(req, res) {
26 res.writeHead(303, {
27 ’Location’: ‘/posts’
28 });
29 res.end();
30 }
1行目で、handleという関数を設定します。
3-7行目で、/posts パスへのアクセスが GET であった場合の動作を設定しています。
4~5行目で、リクエストがあった際の関数の挙動が実装されています。
その内容は、成功を示すステータスコードである200と、どこからのアクセス化などの情報を表示する様に設定しています。
その情報を表示するために、Content-Type(内容の形式)を通常テキスト(text/plain)、charset(文字セット)をutf-8に指定しています。
7行目で、ファイル△△で実装したページを表示するように設定しています。
9-18行目で、/posts パスへのアクセスが POST であった場合の動作を設定しています。
11行目で、データを受け取るというdataというイベントが発生した際の動作を設定しています。
12行目で、受け取ったデータを細切れな状態で取得しそれをchunk変数に適応します。そのchunk変数の内容をbody配列に追加します。
13行目で、すべてのデータを受信するendイベントが発生した際の動作を設定します。
14行目で、取得したbody配列をすべてつなげて文字列に変換し、
15行目で、URIエンコード化された文字列をデコード(元に戻します)し、それを定数decodedとしています。このdecodedは、内容がkeyとvalueを持った形式になっています。
16行目で、decodedの内容のキーの値の部分を取得し、それを定数contentと設定しています。
17行目で、投稿されました:contentと表示するように設定しています。
18行目で、handleResirectPosts関数を呼び出しています。
25-27行目で、そのhandleResirectPosts関数を設定し、その内容が/postsへのリダイレクトです。ステータスコードは303番に設定しており、このステータスコードはPOSTでアクセスのち、GETでも同じパスにアクセスし直してほしいときに利用します。
リクエストを処理を行うハンドラに振り分けるモジュール設計
続いて、リクエストを処理を行うハンドラに振り分けるモジュール(ファイル名××)を作成します。
const postsHandler = require(‘○○’);
function route(req, res) {
switch (req.url) {
case ‘/posts’:
postsHandler.handle(req, res);
break;
default:
break;
}
}
1行目で、先ほど設計したファイル(○○)を呼び出し、それを定数 postsHandlerとしています。
4-6行目で、 /posts パスにアクセスがあった場合、その内容を postsHandlerの中の handle 関数を実行するように設定しています。
つまり、今回は/posts パスにアクセスがあった場合、○○ファイルの中に実装されているhandle関数を実行します。
HTTPサーバーの起動するモジュール設計
そのhandle関数の内容が記載されているHTTPサーバーの起動するモジュールを設定します。
const router = require(‘××’);
const server = http.createServer((req, res) => {
router.route(req, res);
1行目で、先ほど設定したファイル(××)を呼び出し、それを定数routerとしています。
2-3行目で、router というモジュールの route という関数を呼び出します。
つまり、××というファイル内に設定されているroute関数を呼び出します。
今後route関数により、必要なリクエストの振り分け処理を行ってくれるように設定します。
以上で、投稿する機能の実装が完了になります。最後に、投稿フォームを設計します。
投稿フォームの設計
GETメソッドによるアクセスがあった場合に投稿フォームが表示されるように設計します。このとき使うのがtextarea要素です
textarea
textarea 要素は、フォームで複数行に渡る文章を入力するための部品です。今回は、 /posts に POST メソッドで投稿するようにしています。
form(method=”post” action=”/posts”)
div
textarea(name=”content” cols=40 rows=4)
1行目で、postメソッドを利用して/postsに情報を投稿するように設定しています。
3行目で、複数行での文章入力を可能にしています。
今回は、秘密の匿名掲示板の要件の中の「投稿する」という機能を実装しました。
次回は、認証されたユーザーのみ投稿一覧が表示される機能を作成します。