情報収集どうしてますか?2020年版

f:id:takaheraw:20201214105003p:plain

(この記事は READYFOR Advent Calendar 2020 - Qiita の14日目の記事です。)

こんにちは。バックエンドエンジニアの安本です。

先月行われたリモート開発合宿の雑談で、「情報収集どうしてますか?」という話があったので、今更ながら自分の方法を晒してみます。 ハッキリ言って10年変わっていないです。もはや、ロストテクノロジーと言われています。

yamdas.hatenablog.com

ワークフロー

全てをRSSリーダーで済ませたいというモチベーションでこうなっています。

f:id:takaheraw:20201213111506p:plain
rss

ツール

ルーティン作業

  • 「j」,「k」を押して、タイトルを眺める。
  • 気になるものは、「b」でバックグランドで表示させていく。
  • バックグランドで表示させた記事をチラ見していき、気になるのはあとで読む「Google Keep」へ。
  • Google Keep」に保存した記事を、週末などの時間があるときに読み、よい記事はストック用の「はてブ」へ。
  • 仕事で(使えそうな|共有したい)ネタは、社内slackチェンネルにポストへ。

f:id:takaheraw:20201213175655g:plain
画面録画.mp4

(自分にとって)価値のあるフィード

まとめ

最近こういう記事を見かけなくなり、みんながどうしてるのか不安になったので敢えて書いてみました。パーソナライズされたニュースや、流れてくるSNSのTLはもちろん利用していますが、エンジニアたるもの情報を自分でPullしたいですよね。ということで、未だにRSSを利用しているよというお話でした。We need feed!!!

READYFOR Advent Calendar 2020 - Qiita 明日の担当は feat2kj です。よろしくお願いします!!!

NodeのWebアプリケーションフレームワーク Express

サーバサイドJavaScript Node.js入門 を年末に一読したのでまとめ。

Express

ルーティングやセッション管理、静的ファイル配信など限られた機能のみを提供する軽量フレームワーク

インストール

# node -v
v0.8.16
# npm install express -g
# express -V
3.0.5

スケルトンの作成

オプションとしてsessionのサポート、テンプレートエンジンにEJSを指定

# express express_sample -s -e

依存するモジュールは、package.jsonに記述されるのでnpm installコマンドで解決できる。依存モジュールは、express_sample/node_modulesにインストールされる。

# cd express_sample
# npm install

アプリケーションの起動

# node app.js
Express server listening on port 3000

スケルトのディレクトリ構造

.
├── app.js
├── node_modules/
├── package.json
├── public
│   ├── images
│   ├── javascripts
│   └── stylesheets
│       └── style.css
├── routes
│   ├── index.js
│   └── user.js
└── views
    └── index.ejs

app.js

/**
 * Module dependencies.
 */

var express = require('express')
  , routes = require('./routes')
  , user = require('./routes/user')
  , http = require('http')
  , path = require('path');

var app = express();

app.configure(function(){
  app.set('port', process.env.PORT || 3000);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'ejs');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(express.cookieParser('your secret here'));
  app.use(express.session());
  app.use(app.router);
  app.use(express.static(path.join(__dirname, 'public')));
});

app.configure('development', function(){
  app.use(express.errorHandler());
});

app.get('/', routes.index);
app.get('/users', user.list);

http.createServer(app).listen(app.get('port'), function(){
  console.log("Express server listening on port " + app.get('port'));
});

起動環境の指定方法は、NODE_ENVを指定する

# NODE_ENV=production node app.js

ルーティングハンドラ

app.jsのapp.get()の第1引数がルーティングパス。第2引数はコールバック関数。

app.get('/', routes.index);

routes/index.jsのコールバック関数は、resとresを引数に受け取ってres.render()でレンダリングして結果をレスポンスとして返す。

exports.index = function(req, res){
  res.render('index', { title: 'Express' });
};

レンダリングされるviews/index.ejs

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1><%= title %></h1>
    <p>Welcome to <%= title %></p>
  </body>
</html>

Expressのミドルウェア

bodyParser

リクエストボディの内容をJavaScriptのオブジェクトにパースしてnext()を実行。

methodOverride

リクエストボディ内に_methodというパラメータがあった場合、その値でHTTPメソッドを上書きし、next()を実行。

cookieParser

リクエスト内のCookieをオブジェクトにパースし、next()を実行。

session

専用のCookieを用いてセッション管理し、next()を実行。

router

リクエストパスに対応するルーティングハンドラがある場合、それを呼び出すことでレスポンスを返し、なければnext()を実行。

router

リクエストパスに対応する静的ファイルが存在した場合はそのファイルをレスポンスとして送信。なければnext()を実行。

errorHandler

アプリケーション内で発生したエラー処理。

リクエストの処理

f:id:takaheraw:20130105123317p:plain

Node Inspectorを利用したGUIデバッグ

サーバサイドJavaScript Node.js入門 を年末に一読したのでまとめ。

インストール

# npm install node-inspector -g

Node Inspectorの起動

f:id:takaheraw:20130104232627p:plain

debug_http.js

var http = require('http');
var server;
var port = 8888;
server = http.createServer(function(req, res){
  res.writeHead(200);
  res.end('hello world');
});
server.listen(port);
console.log('listening on http://127.0.0.1:' + port);

--debugでデバッグ対象プロセス起動

# node --debug debug_http.js 
debugger listening on port 5858
listening on http://127.0.0.1:8888

Node Inspector起動

# node-inspector

chromehttp://127.0.0.1:8080/debug?port=5858へアクセス。ブレークポイントを設定。

f:id:takaheraw:20130104233153p:plain

http://127.0.0.1:8888にアクセスするとdebugできる。

NodeのI/Oイベントのエラーハンドリング

サーバサイドJavaScript Node.js入門 を年末に一読したのでまとめ。

実在しないファイルの読み込みにエラーが発生した場合、コールバック中に例外をスローしてもtry〜catchで受けれない

# node domain1.js 
uncaughtException: ENOENT, open 'non-exists.txt'

Domainモジュール

Domainは、Node内で発生するエラーオブジェクトのスローやエラーイベントを非同期処理も含むまとまった単位でエラーハンドリングできる機能。node-v0.8で導入された機能。

  • ドメインオブジェクトdとd.run()内で実行される無名関数を結びつけてエラーハンドリング

  • EventEmitterオブジェクトからのエラーイベント発生

NodeのHTTP

サーバサイドJavaScript Node.js入門 を年末に一読したのでまとめ。

HTTPサーバ

HTTPクライアント

HTTPサーバ起動

# node http_server_echo.js 
listening on 1337
=== Raw Socket Data Start ===
POST / HTTP/1.1
Host: localhost:1337
Content-Length: 30
Connection: keep-alive

Hello from HTTP Client Request
=== Raw Socket Data End ===

HTTPクライアント起動

# node http_client.js 
Body Echo: Hello from HTTP Client Request

basic認証のHTTPサーバ

basic認証のHTTPクライアント

HTTPサーバ起動

# node http_server_basicauth.js 
listening on 192.168.11.14:1337

HTTPクライアント起動

# node http_request_basicauth.js 
===== Socket Data =====
HTTP/1.1 200 OK
Content-Type: text/plain
Date: Fri, 04 Jan 2013 09:20:18 GMT
Connection: keep-alive
Transfer-Encoding: chunked

13
Hello Authed World

0


===== Response Data =====
Hello Authed World

HTTP RESTfulサーバ

POST

# curl -X POST -D - -d '{"a":1, "b":2}' http://localhost:1337/foo
HTTP/1.1 200 OK
Connection: close
Content-Length: 0
Date: Fri, 04 Jan 2013 09:30:45 GMT

GET

# curl -X GET -D - http://localhost:1337/foo
HTTP/1.1 200 OK
Content-Length: 13
Content-Type: application/json
Connection: close
Date: Fri, 04 Jan 2013 09:34:37 GMT

{"a":1,"b":2}

PUT

# curl -X PUT -D - -d '{"a":1, "b":2, "c":3}' http://localhost:1337/foo
HTTP/1.1 200 OK
Connection: close
Content-Length: 0
Date: Fri, 04 Jan 2013 09:35:25 GMT

DELETE

# curl -X DELETE -D - http://localhost:1337/foo
HTTP/1.1 200 OK
Connection: close
Content-Length: 0
Date: Fri, 04 Jan 2013 09:36:05 GMT

NodeのTCPサーバ・クライアント

サーバサイドJavaScript Node.js入門 を年末に一読したのでまとめ。

TCPサーバの生成から終了までの流れ

  • TCPサーバを生成する
  • TCPサーバをリッスンする
  • TCPクライアントから接続を受ける
  • TCPクライアントからデータを受信する
  • TCPクライアントにデータを送信する
  • TCPクライアントへのデータ送信が溜まる
  • TCPクライアントへのデータ送信の溜まりが解消する
  • TCPクライアントへから接続終了を受ける
  • TCPクライアントとの接続を終了する
  • TCPサーバを終了する

TCPサーバ

TCPクライアント

サーバ実行

# node tcp_echo_server.js 
Listening Start on Server - 127.0.0.1:11111

クライアント実行

# node tcp_echo_client.js 127.0.0.1 11111
Connected - 127.0.0.1:11111
[S]0: Hello World
[R]0: Hello World
[S]1: Hello World
[R]1: Hello World
[S]2: Hello World
[R]2: Hello World

サーバ側の出力

Connection Start(1/3) - 127.0.0.1:52704
[127.0.0.1:52704] - 0: Hello World
[127.0.0.1:52704] - 1: Hello World
[127.0.0.1:52704] - 2: Hello World

Nodeのストリーム

サーバサイドJavaScript Node.js入門 を年末に一読したのでまとめ。

入力ストリーム

入力ストリームが発生するイベント

  • data
  • end
  • close
  • error

出力ストリーム

出力ストリームが発生するイベント

  • drain
  • error
  • close
  • pipe

ストリームの接続

dataイベント発生時にデータのチャンクを出力ストリームに書き出し、その処理の結果に応じていったん出力を止め、カーネルバッファが空いたら出力を再開する。

入力ストリームのpipe()を使用して上記の処理を簡素化