oinume journal

Scratchpad of what I learned

開発スピードと技術的負債

よくある「開発スピードを優先させるか技術的負債をなるべく発生させないようにするか」という議論、ケースバイケースだとは思うけど、ことプロダクトの立ち上げ段階では、悩んだら「開発スピード」を優先させるようにするべきだと自分は思ってる。

理由は 市場は待ってくれないから。どんなにいいプロダクトでもユーザーに使われなくては意味がないのと、プロダクトを取り巻く外部の環境(競合プロダクトや市場でのニーズ)は自分ではコントロールできないものなのに対して、技術的負債については適切に管理されていればコントロールしながら返済できるから。もちろんバランスも重要だとは思うので、どんな技術的負債も生み出していいかと言われるとそうではないけど。

というわけで自分は「ああこれクソコードだけど機能は満たしてるからそのままリリースしたいなぁ」というのはだいたいクソコードのままリリースしています。(こうやって免罪符を作っているのです)

Mocking a HTTP access with http.Transport in Golang

I've investegated a way to mock HTTP request and response when writing a code to access to a HTTP API with http.Client. Finally, I found that I can do it by just implementing RoundTrip method of http.RoundTripper.

Here is an example of mocking and proxying HTTP request and response. Running with go run main.go -mock mock, you can get mocked result and with go run main.go -mock proxy, you can get proxied result with httptest.Server.

package main

import (
    "flag"
    "fmt"
    "io/ioutil"
    "net/http"
    "net/http/httptest"
    "net/url"
    "strings"
)

var mock = flag.String("mock", "", "Doesn't perform real access when 'proxy' or 'mock' is specified")

func main() {
    flag.Parse()
    client := http.DefaultClient

    if *mock == "proxy" {
        server := newServer()
        defer server.Close()

        client.Transport = &http.Transport{
            // Proxy to httptest.Server which created above
            Proxy: func(req *http.Request) (*url.URL, error) {
                return url.Parse(server.URL)
            },
        }
    } else if *mock == "mock" {
        client.Transport = newMockTransport()
    }

    resp, err := client.Get("http://ifconfig.co/all.json")
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    fmt.Println("GET http://ifconfig.co/all.json")
    fmt.Println(string(body))
}

// Create a HTTP server to return mocked response
func newServer() *httptest.Server {
    return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.WriteHeader(200)
        w.Header().Set("Content-Type", "application/json")
        fmt.Fprintln(w,
            `{
    "Accept-Encoding": [
        "proxy"
    ],
    "User-Agent": [
        "proxy"
    ],
    "X-Ip-Country": [
        "Japan(Proxy)"
    ],
    "X-Real-Ip": [
        "192.168.1.1"
    ]
}`)
    }))
}

type mockTransport struct{}

func newMockTransport() http.RoundTripper {
    return &mockTransport{}
}

// Implement http.RoundTripper
func (t *mockTransport) RoundTrip(req *http.Request) (*http.Response, error) {
    // Create mocked http.Response
    response := &http.Response{
        Header:     make(http.Header),
        Request:    req,
        StatusCode: http.StatusOK,
    }
    response.Header.Set("Content-Type", "application/json")

    responseBody :=
        `{
    "Accept-Encoding": [
        "mock"
    ],
    "User-Agent": [
        "mock"
    ],
    "X-Ip-Country": [
        "Japan(Mock)"
    ],
    "X-Real-Ip": [
        "192.168.1.1"
    ]
}`
    response.Body = ioutil.NopCloser(strings.NewReader(responseBody))
    return response, nil
}

I think it's very simple to mock a HTTP request in GoLang. net/http package is awesome.

Go Programming Blueprints

Go Programming Blueprints

Changing bower package cache directory

bower caches packages in ~/.cache/bower. How can I change the directory? bower's document says "Add the following in .bowerrc" but it's totally wrong.

"storage": {
  "cache" : "~/.bower/cache",
  "registry" : "~/.bower/registry"
}

I try the configuration and run bower install but nothing changed. I finally found out correct configuration in bower/config repo.

"storage": {
  packages: ".bower/packages",
  registry: ".bower/registry"
}

Why the document of famous software such as bower is wrong?

TypeScript Essentials

TypeScript Essentials

2015年の抱負

一年の計は元旦にあり、という言葉がありますがこのエントリーは1月4日に書いています。どうもこんにちは。あまり一年の目標は立てずにフラフラと生きてきたんだけど、アラフォーに近づいてきてそろそろ自堕落な生き方に危機感を覚えてきたので今年の目標を書いておく。

Dockerを実戦投入する

仕事では余裕なくてDocker使ってないんだけどちゃんと使って運用できるようにしたい。早くEC2 Container Service使えるようにならないかなぁ。

英語でブログエントリーを書く割合を25%にしてみる

英語なりプログラミング言語は使う機会がないとドンドン衰えちゃうんだけど、残念ながら職場ではドキュメントを読む以外ではまったく必要ないので、このブログのエントリーで英語の割合を増やしてみようと思う。というわけで日本人以外にも読めるようにブログタイトルを変えてみた。

フロントエンド(Web)を頑張る

ReactとTypeScriptを習得したい。ネイティブアプリ系はそのうち消え行くと思うのであえてやらない。

Reactive Programmingをちゃんと理解する

Reactive Programmingが今年は来そうな気がするのでちゃんと理解して使えるようにしたい。

アルゴリズムを深く理解する

よく使われるdeflateとかB+Treeとか、実際に自分で実装してみて中身まで理解しないとなぁと思う今日このごろ。普通にWebサービスを作っているだけだと「データベースからデータを取得したものをちょい加工して返す」みたいなプログラムしか書かなくてアルゴリズム回りの知識をアップデートできないので。

2014年振り返り

1/3に2014年の振り返りをしている時点ですでに周回遅れになっているわけですが... 技術的な振り返りは2014年に使ってみた技術に書いたので、仕事やプライベートのことを振り返ってみる。

  • 仕事では7月ぐらいにゲーム系じゃなくてメディア系を立ち上げる部署に異動した。Unityを触ったりしたんだけど、やっぱりゲームを作るのは相当な労力がいるし自分には向いてないんじゃないかなぁと思ってメディア系の部署へ。あと今回は第一線でバリバリ開発する立ち位置なので今は産みの苦しみを絶賛味わってます。あとちょっと...
  • プライベートでは、1月ぐらいに車をお義母さんからゆずってもらって15年ぶりぐらいに車を運転してみた。15年間ペーパードライバーだったんだけど、奥さんが妊娠してたので強制的に病院の送り迎えをすることになり、近距離ならなんとか運転できるようになってきた。人だけは轢かないように心がけてる。車種はトヨタのAllionっていうセダン。すでに12万キロ走っているのでそろそろ壊れる気がする。
  • あと人生の一大イベントで4月に息子が生まれててんやわんや。でもとてつもなくかわいくて毎週成長を見るのが楽しい。仕事できる時間が減り、自分の時間もほぼゼロになってしまったけど、息子を育てる方が社会に貢献できている気がするw 出生率があがれば高齢化社会や人口減少問題が緩和されるらしいので、もう一人ぐらい頑張りたいところ。
  • 飼い猫のししまるが2歳に。2014年は年初から誤飲事件が発生して救急病院に通った。おかげでペット保険の必要性を認識して加入。その後ちょいちょい医者にかかっているのでこれは入っておいてよかったなと思う。今はししまる毎日元気に走り回って息子の攻撃からもひらりと身をかわしている。
  • Amazonでモノを買うのを辞めて、yodobashi.comのヘビーユーザーになった
  • ライブは2月にAvril、11月にKnotfestでKORNを見たぐらい。毎年行っていたサマソニも自粛したので今年こそ行きたい。KORNまた今年も来日しないかな。