20190909のGoに関する記事は3件です。

[Go]Ginを使った、すっきりルーティングのサンプル

はじめに

今回は、簡単な内容ですが、Ginでのルーティングファイルについて、共有させて頂きます。

サンプルコード

以下のファイルは、それぞれ
$HOME/go/src/github.com/myProject/myRepository/直下にあるとします。
ghqでプロジェクト管理した感じを想定してます。

server/routes.go
package server

import (
    "net/http"
    "github.com/myProject/myRepository/handler"
    "github.com/gin-gonic/gin"
)

func defineRoutes(r gin.IRouter) {
    v1 := r.Group("/")
    {
        v1.GET("/test", handler.myFunction)
    }
}
handler/yay.go
package handler

import (
    "github.com/gin-gonic/gin"
)

func myFunction(c *gin.Context) {
    // ここに処理を書く
}
実際にアクセスする際のURL
http://hogehoge.com/test

関数の定義でスッキリさせる

server/routes.go下方
func defineRoutes(r gin.IRouter) {
    v1 := r.Group("/")
    {
        v1.GET("/test", handler.myFunction)
    }
}

ここでv1を用意することで、URLが増えてきても、すっきり分かりやすく追加していける。
ちなみに、たくさんルーターを用意した場合、こんな感じになります。

ルーターが増えてきたときのイメージ
    v1 := r.Group("/")

    {
        v1.GET("/test", handler.myFunction)
    }
    {
        v1.POST("/test2", handler.myFunction2)
        v1.PUT("/test2/create", handler.myFunction3)
        v1.GET("/test2/hoge", handler.myFunction4)
        v1.DELETE("/test2/delete", handler.myFunction5)
    }
    {
        v1.GET("/test3/fuga", handler.myFunction6)
        v1.GET("/test3", handler.myFunction7)
    }
    {
        v1.GET("/test4/poon", handler.myFunction8)
    }

増えてきても、すっきりしています。
この辺りは、よくあるFWのルーティングファイルの書き方と似ていて分かりやすいですね。

さいごに

今回は、解説なしで共有だけさせて頂きました。
いつか、理解を深めてがっつり解説したい。

最期まで、ありがとうございました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GoでRedisをかるーくいじってみた

はじめに

n番煎じかと思いますが,自分の知識整理もかねてまとめてみました.
Golang で Redis をさくさくいじってみます.本記事では Docker のインストール済みを想定しています.

環境は以下

  • macOS (ver 10.14)
  • Docker (ver 19.3.1)
  • Golang (ver 1.12.7)

ざっくりRedisとは

  • 永続化可能なインメモリデータベース
  • KVS(Key Value Store)
  • 5つのデータ型をサポート
    • string / hash / list / set / sorted set

利点とは

  • 高速
  • シングルスレッドなので,必然的に処理が排他的になる
  • データの生存期間(TTL)が設定できる
  • ランキングの扱い
    • ソートをやってくれるデータ構造があるので.

参考

Redisについては,こちらの記事がすごく丁寧なのでぜひ.
データ構造やコマンドについては,TryRedisをやってみると感覚がつかみやすい気がします.

Redis を構築

まず Docker で Redis の準備を行います.
Docker Image はこちらを使います.

$ docker run --name redis -d -p 6379:6379 redis redis-server --appendonly yes

Redis をローカルにインストール.
(Go で Redis にアクセスできているか確認するときなどに使います.)

$ brew install redis

以下のようになればOK

$ redis-cli
127.0.0.1:6379> 

redisのコマンドをいくつか試してみます.

// key を全て取得
127.0.0.1:6379> KEYS *
(empty list or set)

// SET key value
127.0.0.1:6379> SET test-key test-val
OK

127.0.0.1:6379> KEYS *
1) "test-key"

// key の削除
127.0.0.1:6379> DEL test-key
(integer) 1

127.0.0.1:6379> KEYS *
(empty list or set)

127.0.0.1:6379> exit

Go で Redis を触ってみる

いよいよ本題.Go で Redis を軽く触っていきます.
redigo というパッケージを使用します.

redigo のインストール

go get github.com/gomodule/redigo/redis

実際にやってみる

  • データの登録と取得
redis.go
package main

import(
    "fmt"

    "github.com/gomodule/redigo/redis"
)

// Connection
func Connection() redis.Conn {
    const Addr = "127.0.0.1:6379"

    c, err := redis.Dial("tcp", Addr)
    if err != nil {
        panic(err)
    }
    return c
}

// データの登録(Redis: SET key value)
func Set(key, value string, c redis.Conn) string{
    res, err := redis.String(c.Do("SET", key, value))
    if err != nil {
        panic(err)
    }
    return res
}

// データの取得(Redis: GET key)
func Get(key string, c redis.Conn) string {
    res, err := redis.String(c.Do("GET", key))
    if err != nil {
        panic(err)
    }
    return res
}

func main() {
    // 接続
    c := Connection()
    defer c.Close()

    // データの登録(Redis: SET key value)
    res_set := Set("sample-key", "sample-value", c)
    fmt.Println(res_set) // OK

    // データの取得(Redis: GET key)
    res_get := Get("sample-key", c)
    fmt.Println(res_get) // sample-value
}
実行結果:
$ go run redis.go
OK
sample-value

Redis: 
127.0.0.1:6379> KEYS *
1) "sample-key"

基本的に Redis のコマンドを実行したいタイミングで,Do()を呼び出す.
Do()の戻り値は,interface{}errorなので,型変換をする際は,redis.String()を呼び出す.
パッケージのコードをみた感じだと,intfloat64byteなどへの変換ができそう.呼び出し方は例によってredis.Int()など.

  • 複数の値を同時に登録,取得.かつ TTL をつけてみる
redis.go
package main

import(
    "fmt"

    "github.com/gomodule/redigo/redis"
)

// Connection
func Connection() redis.Conn {
    const Addr = "127.0.0.1:6379"

    c, err := redis.Dial("tcp", Addr)
    if err != nil {
        panic(err)
    }
    return c
}

type Data struct {
    Key string
    Value string
}

// 複数のデータの登録(Redis: MSET key [key...])
func Mset(datas []Data, c redis.Conn){
    var query []interface{}
    for _, v := range datas {
        query = append(query, v.Key, v.Value)
    }
    fmt.Println(query) // [key1 value1 key2 value2]

    c.Do("MSET", query...)
}

// 複数の値を取得 (Redis: MGET key [key...])
func Mget(keys []string, c redis.Conn) []string{
    var query []interface{}
    for _, v := range keys {
        query = append(query, v)
    }
    fmt.Println("MGET query:", query) // [key1 key2]

    res, err := redis.Strings(c.Do("MGET", query...))
    if err != nil {
        panic(err)
    }
    return res
}

// TTLの設定(Redis: EXPIRE key ttl)
func Expire(key string, ttl int, c redis.Conn) {
    c.Do("EXPIRE", key, ttl)
}

func main() {
    // 接続
    c := Connection()
    defer c.Close()

    // 複数データの登録
    datas := []Data{
        Data{Key:"key1", Value:"value1"},
        Data{Key:"key2", Value:"value2"},
    }
    Mset(datas, c)

    // 複数データの取得
    keys := []string{"key1", "key2"}
    res_mget := Mget(keys, c)
    fmt.Println(res_mget)

    // TTLの設定
    Expire("key1", 10, c)
}
実行結果:
$ go run redis.go
MSET query: [key1 value1 key2 value2]
MGET query: [key1 key2]
[value1 value2]

Redis:
127.0.0.1:6379> KEYS *
1) "sample-key"
2) "key2"
3) "key1"

Redis(10秒以上後):
127.0.0.1:6379> KEYS *
1) "sample-key"
2) "key2"

結果として複数の値を得る場合(今回はMGET),型変換を行う場合はredis.Strings()のように末尾にsがきます.他の型でも同様,redis.Intsなど.
TTLの設定については,秒単位で設定を行うEXPIREと,ミリ秒単位で設定を行うPEXPIREがある.

Redis から TTL の確認は,TTL keyで行う.

127.0.0.1:6379> TTL key1
(integer) 4

127.0.0.1:6379> TTL key1
(integer) -2

127.0.0.1:6379> TTL key2
(integer) -1

結果については以下のようになる.

  • 0以上:残りのTTL
  • -1 :TTLが設定されていない場合
  • -2 :key が存在しない場合

終わりに

ここまで読んでいただきありがとうございます!
あまり長くなってしまっても,同じことの繰り返しになってしまう部分も多いのでこの辺りで.
パッケージのコードをみていたら,Do()の結果をmapに格納できる雰囲気が....まだまだ学べそうです.
コードや解釈の間違いなどありましたら,指摘していただけると幸いです.

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

VSCodeにおしゃれな筆記体を導入して、プログラミングを少しでも耐え得るものにする

概要

前置き

エディタ上の芸のないブロック体の文字を眺めていると、なんだか気が滅入ってきます。

そこで、Mediumやdev.toなど海外メディアのプログラミング記事でよく見かける、いい感じにおしゃれな筆記体フォントをVisual Studio Codeに導入し、プログラミングを少しでも耐え得るものにします。

結果

以下の画像のように、VSCodeでコードの要所要所を筆記体に変えました。

手順

フォントのインストール

Fira Code iScriptをインストールします。

Fira Code iScriptは、プログラミング用に最適化されたフォント「Fira Code」に、筆記体を加えたものです。以下がFira Codeの例です。

Windowsであれば、ダウンロードしたttfファイルをダブルクリックすることでインストールできます。

VSCodeのエクステンションのインストール

筆記体をサポートするものなら何でもいいのですが、私はDark ++ Italicを使いました。

フォント設定の変更

VS Codeの「ファイル」=>「基本設定」=>「設定」=>「テキスト エディター」=>「フォント」から、Font FamilyをFira Code iScriptに変更します。

CSSの変更

上までの手順を踏むと、JavascriptやPythonなどでは、いい感じに筆記体が表示されるようになります。

それでも、Go言語などでは、筆記体の箇所が少ないように思えます。そこで、cssをいじって、特定のクラスを持つ箇所は筆記体にします。以下がその例です。

注意!VS Codeのテーマを変更すると、クラス名の割り振りも変更になってしまいます。下の例はDark ++ Italic以外のテーマでは、いい感じに表示されないかもしれません。

.mtki{
        font-size: 1.125em;
        font-stretch: ultra-condensed;
}
.mtk4, .mtk6{
        font-size: 1.125em;
        font-stretch: ultra-condensed;
        font-style: italic;
}

別のテーマを使っている場合などは、VS Codeの「ヘルプ」=>「開発者ツールの切り替え」をして、筆記体にしたい部分のクラス名を調べてください。

余談

単純にフォントの設定を筆記体にするだけだと、以下の画像のようにとても読めたものではなくなります。上記の通り、エクステンションを導入したりやCSSをいじったりする必要があります。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む