albatrosary's blog

UI/UXとエンタープライズシステム

Go on Azure + Angular v4

Azure App ServicesはGoのサポートがあります。現在、Azure App Serviceプラットフォームでサポートされているバージョンは64bit Go 1.4.2とGo 1.5.1です(らしい)。Azure Appサービスを作成してセットアップして、新しいGoアプリに対応し、デプロイメントを設定する必要があります。

Go on Azure

Goを実行させるための手順は次の通り:

  1. 新しいWebアプリケーション(WebApps)を作成します。
  2. github、gitbucketなどにリポジトリーを作成します
  3. WebAppに作成したリポジトリーを登録します
  4. ローカルで server.go を作成しリポジトリーに push します
package main  
import (  
    "fmt"
    "net/http"
    "os" 
)
func handler(w http.ResponseWriter, r *http.Request) {  
    fmt.Fprintf(w, "Hi there - this page was served using Go \\o/")
}
func main() {  
    http.HandleFunc("/", handler)
    http.ListenAndServe(":"+os.Getenv("HTTP_PLATFORM_PORT"), nil)
}

たったこれだけのステップで go をデプロイ&ビルドすることが可能です。

参考記事: Running Go on Azure App Services · Michael McKenna

import で標準でないパッケージ(という表現でいいのか?)を利用する場合は Azure がよしなにやってくれます。つまりgo getコマンドは Azure が自動的にやります。例えば

import (
    "log"
    "net/http"
    "os"

    "github.com/ant0ine/go-json-rest/rest"
)

とした場合、通常はgo get github.com/ant0ine/go-json-rest/restを実行しますがデプロイ時に Azure がやってくれます。超便利!

+Angular

Angular 経由で Hello World を出力します。go は次のようにしました:

package main

import (
  "log"
  "net/http"
  "os"

  "github.com/ant0ine/go-json-rest/rest"
)

func main() {
  api := rest.NewApi()
  api.Use(rest.DefaultDevStack...)

  router, err := rest.MakeRouter(
    rest.Get("/message", func(w rest.ResponseWriter, req *rest.Request) {
      w.WriteJson(map[string]string{"Body": "Hello World!"})
    }),
  )
  if err != nil {
    log.Fatal(err)
  }
  api.SetApp(router)

  http.Handle("/api/", http.StripPrefix("/api", api.MakeHandler()))
  http.Handle("/", http.StripPrefix("/", http.FileServer(http.Dir("."))))

  http.ListenAndServe(":"+os.Getenv("HTTP_PLATFORM_PORT"), nil)
}

参考:go-json-rest-examples/main.go at master · ant0ine/go-json-rest-examples · GitHub

Angular は

template

<h1>
  {{title.Body}}
</h1>

Component

import { Component, OnInit } from '@angular/core';
import { HelloService } from './hello.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  
  title: any = {
    Body: "hoge"
  };

  constructor(
    private hello: HelloService
  ) { }

  ngOnInit () {
    this.hello.get()
      .then(response => this.title = response)
      .catch(error => console.log(error));
  }
}

HelloService

import { Injectable } from '@angular/core';
import { Headers, Http } from '@angular/http';

import { Observable } from 'rxjs';
import 'rxjs/add/operator/toPromise';

@Injectable()
export class HelloService {
  
  private headers = new Headers({'Content-Type': 'application/json'});
  private url = '/api/message';

  constructor(
    private http: Http
  ) { }

  public get(): Promise<String> {
    return this.http.get(this.url, {headers: this.headers})
      .toPromise()
      .then(response => {
        return response.json();
      })
      .catch(this.handleError);
  }

  private handleError(error: any) {
    console.error('An error occurred', error);
    return Promise.reject(error.message || error);
  }
}

ng build し goコードのリポジトリに配置、github push で終了!

f:id:albatrosary:20170407154549p:plain

http://osctokyo.azurewebsites.net/

Azure 凄いのねぇ〜