
「小」または「li'l」を意味するペルシャ語。いちゃつくときは女の子を参照するためによく使用されます(意味を持って、li'lの女の子)
都市辞書
Koochoolooへようこそ:Golangアプリケーションの開発を合理化するために作成されたエレガントで実用的なプロジェクト。よく組織化されたアーキテクチャを誇るKoochoolooは、データベースの取り扱いや構成管理などの重要な機能を統合し、GOで堅牢なRESTアプリケーションを構築する際のベストプラクティスを例示しています。
init機能はありません:物事をシンプルに保つために、グローバルとinitの複雑さを避けます。fx依存噴射フレームワークとして活用すると、 Koochoolooが配信します。
fxの使用をサポートおよび簡素化する環境。Koochoolooとの旅に着手し、GOで安らかなアプリケーションを作成するためのアプローチを再定義します。スキルセットを拡大している場合でも、複雑なアプリケーションのための強固な基盤を構築する場合でも、 Koochoolooは効率的でクリーンでスケーラブルなソフトウェア設計のパートナーです。
まず、 cmdパッケージには、Cobraを使用したこのプロジェクトのバイナリが含まれています。プロジェクトの開始フェーズで実行できるデータベース移行などのタスク用の単純なバイナリを用意するのは良いことです。各バイナリにはmain.goがパッケージに含まれており、 Register関数でそれ自体を登録します。 cmdのroot.goでは、サブコマンドからのこれらのRegister関数が呼び出されます。レジスタ関数の例は次のとおりです。
// Register server command.
func Register ( root * cobra. Command ) {
root . AddCommand (
& cobra. Command {
Use : "server" ,
Short : "Run server to serve the requests" ,
Run : func ( _ * cobra. Command , _ [] string ) {
fx . New (
fx . Provide ( config . Provide ),
fx . Invoke ( main ),
). Run ()
},
},
)
}繰り返しますが、各コマンドはそのフラグを単独で登録するため、他のコマンドから分離します。コマンド間でフラグを共有する必要がある場合があり、構成にそれらを置く方が良い場合があります。後の場合、 koanf以下のように構造を支援できます。
func Register ( fs * pflag. FlagSet ) {
fs . StringP (
"url" , "u" ,
nats . DefaultURL ,
fmt . Sprintf ( "nats server url(s) e.g. %s" , nats . DefaultURL ),
)
}この関数レジスタ共有フラグをレジスタにし、次の関数を使用してそれらに基づいて構成をロードします。
k := koanf . New ( "." )
if err := k . Load ( posflag . Provider ( fs , "." , k ), nil ); err != nil {
log . Errorf ( "error loading config.yml: %s" , err )
}
if err := k . Unmarshal ( "" , & instance ); err != nil {
log . Fatalf ( "error unmarshalling config: %s" , err )
}各アプリケーションの主要部分は、その構成です。プロジェクトに構成ファイルから環境変数までの構成を作成するには、多くの方法があります。 Koanfはそれらすべてを1つの美しいパッケージに入れています。ここでの主なポイントは次のとおりです。
configモジュールで定義されているため、開始時に渡されます。PS Koanfは、構成を入力するためにViperよりもはるかに優れています。入力された構成とは、構成用の定義された構造があり、多くのソースから構成をロードすることを意味します。
Koanfをインストールするには、次のコマンドを使用できます。
go get -u github.com/knadh/koanf/v2
go get -u github.com/knadh/koanf/providers/file
go get -u github.com/knadh/koanf/providers/env
go get -u github.com/knadh/koanf/providers/structs
go get -u github.com/knadh/koanf/parsers/tomldomainパッケージで定義されているパッケージとサービスは、サードパーティパッケージを使用せずにdomainの他のパッケージのみを使用します。これらのパッケージとサービスは、コアドメインの概念を指定します。
データベースへの接続を担当するdbパッケージがあります。このパッケージはconfigモジュールで定義され、データベースインスタンスを作成するデータベース構成を使用します。今後のデータベースインスタンスに完全に自信を持っているために、ここでデータベースをpingすることをお勧めします。また、データベースの健康に関する洞察を得るために、このping関数を定期的に呼び出して、その結果をメトリックで報告することができます(ここではしませんでした)。
プロジェクトモデルはmodelパッケージで定義されています。これらのモデルは内部で使用されますが、 responseまたはrequestパッケージで使用できます。このパッケージには、データベースと通信するための構造はありません。
リポジトリは、モデルを保存または取得するためにデータベースと通信する責任があります。リポジトリはinterfaceであり、それらのための具体的で模擬実装があります。具体的な実装はメインコードで使用され、モックされたものはテストに使用されます。リポジトリのテストは扱いにくく、実際のデータベースで行われていることに注意してください。
HTTPハンドラーは、 handlerパッケージで定義されています。 Echoは、必要なEveythingを備えた素晴らしいHTTPフレームワークです。各ハンドラーには、特定のルートグループにルートを登録するRegisterメソッドを備えた構造があります。ルートグループは、特定の親パスの下でルートをグループ化するためのエコーフレームワークの概念です。各ハンドラーには、その構造に必要なものがあります。ハンドラー構造はmain.goで作成され、グループに登録します。
type Healthz struct {}
// Handle shows server is up and running.
func ( h Healthz ) Handle ( c echo. Context ) error {
return c . NoContent ( http . StatusNoContent )
}
// Register registers the routes of healthz handler on given echo group.
func ( h Healthz ) Register ( g * echo. Group ) {
g . GET ( "/healthz" , h . Handle )
}すべてのメトリックは、オープンテレメトリーに基づいてプロメテウスを使用して収集されます。各パッケージには、構造がメトリックを含み、それらを変更する方法を定義するmetric.goがあります。プロメテウスから別のサービスに移行するには、 telemetry変更するだけです。メトリックはグローバルではなく、オープンテレメトリーデザインのおかげで、それぞれのインスタンスごとに別々に作成されました。メトリックエンドポイントでより良いコントローラーを持つために、監視用のtelemetryパッケージで定義されている別のHTTPサーバーがあります。
リクエストと応答のためにパッケージを分離することは良いことです。これらのパッケージには、検証ロジックも含まれています。 Goの適切な検証パクケージの1つは、Ozzo-Validatorです。検証メソッドを提供した後、リクエストを取得した後、メソッドを簡単に検証できます。
アプリケーションの最も重要な部分を記録します。最初は、単純なstdoutログ以上のものを持っている必要はありません。しかし、将来的には、テキストログからの問題を検出するとシステムが成長すると、ログを記録して集約システムに発送する必要があります。
Zapは、構造ロギングに最適なロガーです。 zap 、それを子供モジュールに渡すことを強制し、 Namedメソッドを備えたロガーにも名前を付けます。名前付きロガーを使用することで、ログアグリゲーターにモジュールログを簡単に見つけることができます。
このプロジェクトにはMongoDBのみが必要であり、提供されたdocker-composeで実行できます。
cd deployments && docker-compose up -d
cd cmd/koochooloo/ && go build && ./koochooloocurl -X POST -d ' {"url": "https://elahe-dastan.github.io"} ' -H ' Content-Type: application/json ' 127.0.0.1:1378/api/urls
curl -L 127.0.0.1:1378/api/CKaniA checks.....................: 99.83% ✓ 2995 ✗ 5
data_received..............: 2.0 MB 64 kB/s
data_sent..................: 521 kB 17 kB/s
group_duration.............: avg=649.18ms min=153.18µs med=265.45ms max=30.95s p(90)=1.61s p(95)=2.06s
http_req_blocked...........: avg=14.12ms min=0s med=3µs max=1.65s p(90)=13µs p(95)=147.04µs
http_req_connecting........: avg=6.23ms min=0s med=0s max=1.36s p(90)=0s p(95)=0s
http_req_duration..........: avg=272.98ms min=0s med=127.99ms max=4.81s p(90)=830.93ms p(95)=1.29s
http_req_receiving.........: avg=125.23µs min=0s med=60µs max=11.21ms p(90)=228µs p(95)=363µs
http_req_sending...........: avg=50.78µs min=0s med=22µs max=7.28ms p(90)=86µs p(95)=138µs
http_req_tls_handshaking...: avg=7.86ms min=0s med=0s max=653.63ms p(90)=0s p(95)=0s
http_req_waiting...........: avg=272.8ms min=0s med=127.71ms max=4.81s p(90)=830.87ms p(95)=1.29s
http_reqs..................: 4000 129.093962/s
iteration_duration.........: avg=1.29s min=142.34ms med=1.04s max=30.97s p(90)=2.18s p(95)=2.64s
iterations.................: 1000 32.273491/s
vus........................: 100 min=100 max=100
vus_max....................: 100 min=100 max=100