スキップしてメイン コンテンツに移動

自動生成されるファイル

自動生成されるファイル

先ほどのサンプルアプリケーションの作業ディレクトリには、
以下のファイル・ディレクトリがあります。

design/
app/
client/
swagger/
tool/
helloworld.go
main.go

一つ一つ見ていきましょう。

生成物一覧


design/design.go


これは、最初に実装したデザインファイルになります。
アプリケーションの枠組みを決める設計図のようなものです。

goa独自のDSL(domain-specific language)を使って、APIの仕様を定義していきます。

app/


ここには、デザインされたアプリケーションの、実際に動くコードが生成されていきます。
基本的に、このディレクトリに格納されたファイルは編集不可(できるけど、しちゃだめ)と考えて良いです。

プログラマが追加実装しても、次にまたコード生成した場合、プログラマの追加実装は上書きされて消されてしまいます。


app/contexts.go


コンテキストが実装されています。
goaでは基本的に、API一つ一つに対して対応するコンテキストが実装されていきます。

コンテキストとは、HTTPリクエストを受け付けてからレスポンスを返すまで、
一連の流れが終わるまでの状態を表します。

2つのHTTPリクエストがあった場合、コンテキストは別々のオブジェクトとなります。
どのHTTPリクエストなのかを識別できるような、リクエスト毎の固有情報ですね。

コンテキストは3つのプロパティを持ち、

type ShowHelloworldContext struct {
  context.Context
  *goa.ResponseData
  *goa.RequestData
}

Go標準のContextと、リクエスト・レスポンスを持っています。

app/controllers.go


コントローラのinterfaceが定義されています。
コントローラとは、Webアプリケーションでよく使われるデザインパターンMVC(Model View Controller)のControllerです。

コントローラはResource単位で生成され、今回のサンプルで言うと
HelloworldControllerというinterfaceが定義されています。

app/hrefs.go


各リソースに対してのhref(リンク=URIのPath)が定義されています。

app/media_types.go


MediaTypeが実装されています。
MediaTypeとは、Request・Responseのインターフェース(type interfaceではなく、一般語)を定義したもので、
どういうパラメータを、どういう形式で返すかなどの取り決めを具現化した構造体が定義されています。

app/test/helloworld_testing.go


コントローラをテストする為のファイルになります。
※テストについては、別の章で紹介します。


app/user_types.go


ユーザー定義のTypeが実装されます。
今回のサンプルでは使いませんでしたが、
desgin/design.goで、以下のような Type DSLで定義されたものから生成されます。

var HogeHogePayload = Type("HogeHogePayload", func() {
    ・・・
})


helloworld.go


app/controllers.goで定義されたinterface HelloworldController
具現化した構造体が実装されています。
HellowWorldリソースのアクションは全て、このファイルに実装していきます。
このファイルは編集可能です。

次回、goagenでコード生成してもファイルが存在する場合は上書きされません。
逆にいうとデザインファイルにアクションを追加しても、
次回からアクションに対応するメソッドを生成してくれなくなり、プログラマが自ら実装追加する必要があります。


main.go


goasampleのエントリーポイントです。
アプリケーションの初期化をし、HTTP Serveする処理が実装されています。
このファイルは編集可能です。

このファイルも、コントローラ毎の実装ファイルと同じく編集可能です。
次回、goagenでコード生成しても、ファイルが存在する場合は上書きされません。


client/


クライアントサイドからAPIコールする際に使えるライブラリが置かれています。
APIの検証や、他のGoアプリケーションからimportして使用する事ができます。

  • client/helloworld.go
  • client/media_types.go
  • client/user_types.go

APIのインターフェース(Request/Response構造体)は、app/media_types.goで定義されているものと同等のものが同じように実装され、コードが共有されている訳ではありません。

つまり、appディレクトリとclientディレクトリは、それぞれ独立しているという事です。
これは、他のアプリケーションから参照される場合、依存関係が完全に断ち切られているので、他のアプリケーションがappディレクトリ内のコードを使うような必要はありません。

基本的に、編集不可です。


swagger/


ドキュメントが生成されています。
形式はswagger(json/yaml)の2ファイルが作られています。

  • swagger/swagger.json
  • swagger/swagger.yaml

基本的に、編集不可です。
余談ですが、blueprint形式に変換するサードパーティがあります。

https://github.com/apiaryio/swagger2blueprint

npm install -g swagger2blueprint

swagger2blueprint swagger/swagger.yaml


tool/


APIを検証できる、CLIが生成されています。

  • tool/cli/commands.go
  • tool/goasample-cli/main.go

clientディレクトリを参照しています。
各APIをコマンドラインから検証可能です。

例えば、helloworldリソースのshowアクションを検証したい場合は

go run tool/goasample-cli/main.go show helloworld
2017/05/29 07:00:22 [INFO] started id=spwT58UC GET=http://localhost:8080/
2017/05/29 07:00:22 [INFO] completed id=spwT58UC status=200 time=42.483851ms
Hello World!

といった具合に、goasampleにアクセスしてくれます。
せっかくなので以降curlではなく、こちらのclientを使っていく事にしましょう。
基本的に、編集不可です。


感想

たった一つのデザインファイルdesign/design.goから

  • 土台(リクエストパラメータ、コンテキスト、コントローラ等々)
  • ドキュメント
  • テストコードの雛形
  • 外部アプリケーションから利用可能なclient
  • APIを検証できるコマンドラインツール

といった、5つの成果物が生成されています。
これだけでもう、リッチな開発環境(IDE)と言っても過言ではないのではないでしょうか。

開発を進めていくには、十分なほどの環境が揃ってしまっています。
次章では、リクエストの定義について、説明していきます。

コメント

このブログの人気の投稿

goa request parameters

Request この章では、APIリクエストのデザインについて説明していきます。
リクエストには、主に3種類、データの渡し方があります。

URLのPathに含まれる、リソースを識別するものとしてのパラメータQueryパラメータ(GETで良く使われる、?に続く文字列ですね)リクエストボディ
他にもHTTPリクエストという点では、HTTPヘッダも存在しますが、
HTTPヘッダはリクエストパラメータというより、
リクエストの形式や認証などに使われる、メタデータ的な意味合いがあるため
この章では扱いません。

それでは、それぞれの詳細を見ていきましょう。
Pathパラメータ RESTFulなAPIを扱うとき、良く出てくる

/user/:id -> /user/100
/product/:category/:product_id -> /product/book/300
のような、URLに含まれるパラメータですね。
正式名称は何というのでしょうか。

このパラメータは、Resourceを識別するために使われます。
Queryパラメータで識別しても良いのですが、Queryパラメータはどちらかというと、
APIの振る舞い・挙動を変える意味合いがあります。

この辺の考えは、RESTfulというアーキテクチャの話になってくるため、ここでは割愛します。

それでは実装してみましょう。
先ほどまでのソースコードを一旦、コミットします。
$ git add . $ git commit -m "first commit"
そして、デザインファイルにResourceを追加します。
var _ = Resource("products", func() { Action("show", func() { Routing(GET("products/:category_id/:product_id")) Params(func() { Param("category_id", Integer, "カテゴリID") Param("product_id", Integer, "プロダクトID") …

goa -Golang Web Application Framework-

Webアプリケーションフレームワーク goa
goaとは、GolangでWebアプリケーションを構築していくフレームワークです。

今流行りのマイクロサービスやAPIサーバを早急に構築できます。(HTMLを返すWebサーバももちろん、実装可能です)

早急といった言葉を使ったのは、Webアプリケーションを構築する際の

ルーティングリクエストパラメータの定義レスポンスパラメータの定義パラメータのバリデーションコントローラの定義
といった、ビジネスロジック以外の土台部分を自動で生成してくれて、
ビジネスロジックの実装に専念できるからです。

自動生成といっても、思い描いたものが勝手にできる訳ではなく、
goa独自のDSLを記述してアプリケーションの仕様を定義する(デザインする)必要があります。

goaではアプリケーションの枠組みを、design.go(デザインファイル)というAPIの定義書を作って生成していきます。

DSLを覚える学習コストはありますが、それに見合った以上の働きをしてくれます。

Webアプリケーションのフレームワークとして有名なRuby on Railsも、
お作法を知らないと、レールから外れた実装をする事になり複雑な実装になってしまいます。

が、Railsは世界中で使われてる有名なフレームワークとなっています。
その学習コスト以上に見合った以上の働きがあるからでしょう。

goaは、ビジネスロジックに没頭できる点において、Railsに匹敵できるほどポテンシャルを持っていると思います。
もちろん、RubyではなくGo言語なので、言語仕様上の違いがあり単純に比較はできません。

このブログでは、自分の学習結果のアウトプットとして、goaについての紹介を連載していきたいと思います。