2018-12-01から1ヶ月間の記事一覧
Webサーバとブラウザ間で状態を管理する通信プロトコル、その管理の中でブラウザに保存された情報を指します。 主な用途は、ショッピングサイトのカートの状態などで、ユーザーが操作した情報を一定期間保存して利便性を高めるために使われます。 動作 サー…
Dockerに代表されるコンテナ型仮想化は、 1つのOS環境に、コンテナと呼ばれる分離された空間を作成し、コンテナごとに異なるOS環境(version)を実現します。 コンテナは、あくまで一つのOSの上に成り立っているため、物理マシン上で一般的な「OSブート手順…
http.Redirect() 303、307の例をお見せします。 記述内容が異なるのは、http.Redirect()の第4引数のみです。 templateであるindex.gohtmlです。 formのaction属性に「/bar」を指定します。 <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form method="POST" action="/bar"> <input type="text" name="fname"> </form></body></html>
使用ケース 307 Temporary Redirectは、リクエストされたリソースが一時的に異なるURLに移動されたことを意味します。 元のリクエストメソッドがそのまま移動先へのリクエストメソッドとなります。 したがって、301や303と違い、POSTがGETに変更されることは…
使用ケース 303 See Otherは一般的に、PUTやPOSTの結果として返されるステータスコードです。 例えば掲示板などでPOST送信した後に再び書き込み一覧を表示してしまうと、その画面を再読み込みした場合に、再度同じPOSTを送信できてしまいます。 これを防ぐた…
使用ケース 301 Moved Permanentlyは、恒久的にURLが移転された際、その新しいURLへのリダイレクトとして使用されます。 サイトが全く異なるURLに移転したケースはもちろん、SSL化してhttpからhttpsに変更された際にも使用します。 また、SEOの観点からURLを…
1つのクラスがあまりに多くの仕事をこなしている場合は、大抵、インスタンス変数の持ちすぎになっています。 インスタンス変数が多すぎると、重複したコードが生まれやすくもなります。 まず「クラスの抽出」を適用して、いくつかの変数をまとめます。ポイン…
状況 複数のクライアントが、あるクラスの一部の機能を使っている 対処 共通部分をインターフェースとして抽出する メリット 各クライアント(関数など)がどの機能を必要としているのかが明確になる 別の機能を持たせた異なる種類のクライアントを作成する…
http.Requestのポインタをレシーバに持つFormFile()を使います。 次のような階層があるとして、 main.go templates index.gohtml filestore (作成したファイルを格納) formのinputからファイルを読み込み、 filestoreフォルダに新たなファイルを作成、 読み…
空のディレクトリを作成して、その変更をgitに認識させるために 空ファイルを作成したい時には.gitkeepを作成します。 名称が「.」で始まるファイルはGUIからは作成できないので、 コマンドラインツールを使います。 ※Visual Stadio Codeからは作成可能です…
強制的に404 Not Found Errorを返します。 例えばfavicon.icoを配置していないと、ブラウザによってはアクセスする度にエラーログが吐かれてしまいますが、 http.NotFoundHandler()を使って、"/favicon.ico"に対してHandleを指定すると、 エラーログを出力し…
favicon.icoは、ブラウザのタブやお気に入り登録時に表示される画像ファイルです。 ブラウザのブランド力を高める目的として、1999年にMicrosoftのIE5から発表されました。 その後はWeb標準として扱われ、HTML5でも標準規格とされています。 HTMLのheadの中…
ResponseWriterにエラーの内容を書き込むことができ、 クライアント側にエラーを認知させることができます。 func pict(w http.ResponseWriter, req *http.Request) { f, err := os.Open("pict.png") if err != nil { http.Error(w, "file not found", 404) …
http.Handle()とhttp.FileServer()を用いた、サーブ方法には問題となる点がありました。 http.FileServer()で階層ごと複数ファイルをサーブする【Go】 - 技術向上 http.Handle("/abc/", http.FileServer(http.Dir("templates"))) 上記の場合、/abc/にアクセ…
http.FileServer()関数を使って、階層ごと複数ファイルをサーブすることができます。 返り値の型はHandlerです。 よって、指定されたURLにアクセスされた際にHandlerを実行する、 http.Handle()関数の第2引数に指定することができます。 func http.FileServe…
ファイルをサーバーにあげる際に利用します。 io.Copyと比較して、各種ヘッダー情報を付加、利用できる点で利があります。 それはContet-Range、MIMEタイプ、ETagを利用したIf-MatchとIf-None-Match、 If-Range、 さらにIf-Unmodified-Sinceなどで、正確に、…
Reader経由でファイルをコピーして、Writerを通して出力します。 func pict(w http.ResponseWriter, req *http.Request) { // HandlerFunc()の第2引数に指定するため、この形式 f, err := os.Open("pict.png") // ファイルを開き、Readerが使える状態にして…
packageの紹介 こちらのhttprouter packageは、net/http packageのServeMuxよりもルーティングが高速で、かつ使いやすいと評判です。 GitHub - julienschmidt/httprouter: A high performance HTTP request router that scales well パフォーマンスについて…
http.RequestのFormValue()メソッドを使用すると、 queryパラメータから、keyを指定した値の取得ができます。 http packageのHandler型へのダックタイピングを、hotdogという型に対して行う例で解説します。 Handler型はinterface型であり、ServeHTTP()メソ…
http.Requestからformの値を取得するには、 http.Requestのメソッド、ParseForm()事前に実行する必要があります。 その上で、formの値が格納されているhttp.Requestのフィールド(url.Values型)にアクセスします。 formの値が格納されるフィールドには、For…
状況 フィールドがいくつかのサブクラスだけで使われている 対処 対象のフィールドを、サブクラスに移動する メリット クラスの責務が明確になる 手順 対象のフィールドをスーパークラスの全てのサブクラスで宣言する スーパークラスからそのフィールドを削…
状況 スーパークラスの振る舞いが、いくつかのサブクラスだけに関係している 対処 対象のメソッドをサブクラスに移動する メリット クラスの責務が明確になる 手順 スーパークラスの全てのサブクラスで当該のメソッドを宣言し、そこにメソッドをコピーする …
状況 あるクラスの特定のインスタンスだけに必要な特性がある 対処 その一部の特性を持つサブクラスを作成する メリット クラス内の記述量が減り、可読性が上がる 「クラスの抽出」と比較して容易ではありますが、制約があります。 オブジェクトが生成された…
状況 クラスの責務が明確であるとは言い難く、複数のクラスに分けてなされるべき作業を一つのクラスで行なっている 例えば、Personというクラスに電話番号に関するフィールドやメソッドが存在する場合です。 対処 クラスを新たに作成し、適切なフィールドと…
クライアントサイドの処理を行うプログラムを作成します。 netパッケージのDialメソッドを使用します。 サーバーの役割を担うproject、main.goファイル、 サーバーに対してアクセスする、クライアントの役割を担う別のproject、main.goファイルを用意します…
net.ConnのSetDeadline()メソッドを使うと、 接続の有効期限を指定することができます。 func main() { li, err := net.Listen("tcp", ":8080") if err != nil { log.Fatal(err) } for { conn, err := li.Accept() if err != nil { log.Fatal(err) } go hand…
bufio packageのScannerを使って1行ずつ読み込むことができます。 TCP接続した情報を読み込む例を示します。 main.goです。 func main() { li, err := net.Listen("tcp", ":8080") if err != nil { log.Fatal(err) } for { conn, err := li.Accept() if err …
HTTPで動作するサーバーを作成するため、 TCPサーバーを、標準パッケージのnet packageを使って作成します。 TCPはサーバーとクライアント間の接続を事前に確立し、 通信相手ごとに通信の状態を管理します。 それゆえに信頼性は高いですが、コストのかかる通…
処理記述が長いメソッドは、可読性を下げ、適切に部品が共通化されていないことから、 プログラム全体でコードの重複も生まれやすくなります。 「メソッドの抽出」は一番単純で効果のあるアプローチです。 パラメータや一時変数もメソッドを長くする原因です…
状況 メソッド内に、正常ルートが不明確な入れ子の条件付き振る舞いがある double getPayAmount() { double result; if (_isDead) result = deadAmount(); else { if (_isSeparated) result = separatedAmount(); else { if (_isRetired) result = retireAmo…