20210303のGoに関する記事は6件です。

Go 言語でリバースプロキシ

Go 言語の標準ライブラリ net/http/httputil には、リバースプロキシを作るための NewSingleHostReverseProxy 関数が用意されています。この関数を使うことで、Nginx で行うようなリバースプロキシを Go 言語のプログラム上で行うことができます。

下記コードを実行して http://localhost:10000/ にアクセスすると、hello, world が返ってきます。ポート番号 10000〜10003 が使われていると正常に動作しないので注意が必要です。

package main

import (
    "net/http"
    "net/http/httputil"
    "net/url"
    "time"

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

func main() {
    // サーバーを作成する
    s10000 := gin.Default()
    s10001 := gin.Default()
    s10002 := gin.Default()
    s10003 := gin.Default()

    // s10000 へのルートパスのリクエストは s10001 と s10002 を経由して s10003 に渡る
    s10000.GET("/", makeReverseProxy("10001"))
    s10001.GET("/", makeReverseProxy("10002"))
    s10002.GET("/", makeReverseProxy("10003"))
    s10003.GET("/", func(c *gin.Context) {
        c.String(http.StatusOK, "hello, world")
    })

    // 非同期にサーバーを立ち上げる
    go s10000.Run(":10000")
    go s10001.Run(":10001")
    go s10002.Run(":10002")
    go s10003.Run(":10003")

    // プログラムが終わらないようにする
    time.Sleep(time.Hour)
}

func makeReverseProxy(port string) func(*gin.Context) {
    return func(c *gin.Context) {
        remote, _ := url.Parse("http://localhost:" + port)
        proxy := httputil.NewSingleHostReverseProxy(remote)
        proxy.ServeHTTP(c.Writer, c.Request)
    }
}

この仕組を使うことで、モノリシックな Web サーバーを複数の Web サーバーに分割できます。将来は複数のサーバーで運用したいけれど、とりあえずはひとつのサーバーで動かしたいといったときに使えるのではと思っています。

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

【Go言語】特定のTweetにリプライする

用意するもの

・PC(WindowsでもMacでも)
・Twitter API
・Twitterアカウント

やったこと

1.Twitter API準備

色々な方が紹介されていると思いますので、割愛します。

2.Go言語で書く

処理としては、"ジャイアン"を含む自分の過去ツイートにリプライしています。

main.go
package main

import (
    "fmt"
    "net/url"
    "strings"
    . "fmt"

     "github.com/ChimeraCoder/anaconda"
)

//Twitter API認証用メソッド
func GetTwitterApi() *anaconda.TwitterApi {
    anaconda.SetConsumerKey("API Key")
    anaconda.SetConsumerSecret("API secret Key")
    api := anaconda.NewTwitterApi("token", "token secret")
    return api
}

func main(){
    api := GetTwitterApi() //Twitter認証処理呼び出し
    text := "おれさまがジャイアンだ!" //ツイート内容

    v := url.Values{}
    v.Set("count", "10") //取得するツイート数をセット

    x := url.Values{} //リプライするツイート情報を格納する

    tweets, err := api.GetUserTimeline(v) //自分のタイムラインを10件取得
    if err != nil {
        panic(err)
    }

   SearchText := "ジャイアン"

   //取得したツイートに対する処理
    for i, tweet := range tweets {
        //ツイート内容にジャイアンが含まれているか
        if strings.Contains(tweet.FullText, SearchText) {
            id := tweets[i].IdSt
            x.Add("in_reply_to_status_id", id) //xにidを追加
        }
    }

    tweet, err := api.PostTweet(text, x)
    if err != nil {
       panic(err)
    }

     fmt.Println("Finish!")
}

3.参考にしたドキュメント

anacondaで実装したい処理があればやはり公式ドキュメント見るのが一番いいと思いました。

次はいいねbot書きます~!

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

プログラミング超入門(2)〜GO言語〜

データ型について

変数に入れるデータの種類のことを指し、①数値型(number「ナンバー」型)②文字列型(string「ストリング」型) ③ブール型(Boolean「ブーリアン」型)に分けデータを代入する際に、Go言語ではデータ型として指定する静的型付け言語が用いられる。逆に、変数にデータを入れる際にデータを指定する必要がなく自動的に判断してくれるプログラミング言語を動的型付け言語といいます。

数値型には、整数型と小数点型がある

数値型 説明
int コンピューターで表せるだけの範囲の整数値を表す(int8 int32等、-127〜127)
float64 64ビットのコンピューターで少数値を表す(32ビットの場合はfloat32型)
ints.go
package main

import "fmt"

func main() {
    var a int
    a = 4
    b := 6    
    fmt.Println(2 * a)
    fmt.Println(b - a)
}

前回までの応用で、データ型を自動判別させ変数を定義して値を代入し実行してみます。

・実行結果

./ints

8
2

変数自身の値に処理を加える

変数は「変」数という名前から伝わるように、一度値を代入したあとでも別の値を再代入することができ、前にあった変数の値は新しく上書きされて消されます。例えば、a := 100 の下にa = 50 と代入すれば、aの値は50になります。

変数自身の値にを処理して、新しく代入する

変数の元の値を処理してその変数に代入し直す事ができます。

                a = 50 (↓のaには値50が用いられる)
(新しい値80が代入→)a = a + 30

代入演算子の右側では、元の値が使われたうえで処理が行われます。そして、代入演算子の左側の変数に新しい演算子が代入される仕組みです。更に、a = a + 30a += 30のように省略して書くことができます。
省略形には、加算代入(+=)、減算代入(-=)、乗算代入(*=)、除算代入(/=)、剰余代入(%=)があります。

ints.go
package main

import "fmt"

func main() {
    a := 4
    b := 6    
    fmt.Println(2 * a)
    fmt.Println(b - a)

    a = 50
    b += a 
    fmt.Println(a)
    fmt.Println(b)
}

変数自身の値を処理して再代入する処理を追記させて実行してみます。

・実行結果

./ints

8
2
50
56

float64型の宣言を省略した書き方

a := 4.0

floats.go
package main

import "fmt"

func main() {
    a := 4    
    fmt.Println(2 * a)
    fmt.Println(2.0 * a) 
    fmt.Println(2.2 * a)
}

floats.goというファイルを作り、数値の型を確認してみます。

・実行結果

./floats

8
8
8.8

スクリーンショット 2021-03-01 20.39.07.png
変数 a にはint型、変数 b にはfloat64型が渡されている場合、データ型の異なる値同士で減算するとエラーが乗じます。Go言語を始めとしたプログラミング言語の多くは、データ型が異なる数値同士での計算を禁じています。また、Go言語のデータ型は、reflect(リフレクト)のパッケージのTypeOf(タイプオフ)を使用して確認することが出来ます。

nums.go
package main

import ("fmt" "reflect")

func main() {
    num01 := 123
    var num02 int = 123456789
    num03 := 1.23
    var num04 int = 1.23456789    

    fmt.Println(reflect.TypeOf(num01))
    fmt.Println(reflect.TypeOf(num02))
    fmt.Println(reflect.TypeOf(num03))
    fmt.Println(reflect.TypeOf(num04))
}

・実行結果

./nums

int
int
float64
float64

←前回の記事 次の記事へ→

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

string型にnilを入れる黒魔術

良いか悪いかといったら、どう考えても悪い。

package main

import (
    "fmt"
)

type text struct {
    text string
}

func main() {
    var a string
    a = fmt.Sprint(nil)
    fmt.Println(a)
    fmt.Println(a == "nil")
    //fmt.Println(a == nil) //invalid operation: a == nil (mismatched types string and nil)

    var t text
    t.text = fmt.Sprint(nil)
    fmt.Println(t.text)
    fmt.Println(t.text == "nil")
    // fmt.Println(t == nil) // invalid operation: t == nil (mismatched types text and nil)
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

VSCodeでbeegoをデバッグする

はじめに

beegoの学習中に、ブレークしようとしてVSCodeの←をぽちっとしてもぜんぜん止まらなかったのでメモ的に投稿。

前提

  • windows環境
  • beegoインストール済み
  • vscodeインストール済み
  • vscodeにgoの拡張機能インストール済み

delveをインストール

beegoプロジェクトのルートフォルダで下記実行。

$ go get -u github.com/derekparker/delve/cmd/dlv

一応動作確認。下記がでればOK。

$ dlv version
Delve Debugger
Version: 1.5.1
Build: $Id: bca418ea7ae2a4dcda985e623625da727d4525b5 $

launch.jsonを作成

VsCode上で実行タブを押下。
初回は実行ファイルを作成~がでるので押下して作成する。
すると以下のような感じになるはず。
WS000004.JPG

このlaunch.jsonを下記のように変更する。

launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch",
            // "type": "godlvdap",
            "type": "go",
            "request": "launch",
            "mode": "auto",
            "program": "${workspaceFolder}/main.go",
            "env": {},
            "args": []
        }
    ]
}

programがポイントです。
beegoはmain.goを動作させたいので現在フォルダ以下のmain.goを指定。
他の詳細は以下を参考にしてください。

Visual Studio CodeでGo言語のデバッグ環境を整える

ブレークポイントを追加&実行

後は他と同じようにブレークポイントを追加して、VSCode左上のlaunchの▷押下で実行。
処理を通れば無事デバッグできるはず。

WS000005.JPG

おわりに

新しい言語とかやると環境回りで時間とられるなー

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

Go Snippet: 最小限の JSON API サーバー

シンプルな JSON API サーバー。
コピペ用

コード

package main

import (
    "encoding/json"
    "log"
    "net/http"
)

type Post struct {
    ID    int    `json:"id"`
    Title string `json:"title"`
    Body  string `json:"body"`
}

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Add("Content-Type", "application/json")
        if err := json.NewEncoder(w).Encode(&Post{ID: 1, Title: "hello", Body: "world"}); err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
        }
    })
    log.Fatalln(http.ListenAndServe(":8080", nil))
}

確認

ブラウザから http://localhost:8080/ にアクセスする

{
    id: 1,
    title: "hello",
    body: "world"
}

curl -i http://localhost:8080/ でアクセスする

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 40

{"id":1,"title":"hello","body":"world"}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む