序文最近、多くの友人から個人的にメッセージが届きました。彼らは Go の基礎を学んだ後、フレームワークを使用して商用プロジェクトを実装したいと考えていますが、どのフレームワークを選択すればよいか、ましてやどのような商用プロジェクトに取り組むべきかを決めるのに苦労しています。 これらの問題に対処するため、私自身のプロジェクト経験に基づいて、シンプルで使いやすいGo言語のeコマースフロントエンドおよびバックエンドシステムAPIを作成しました。このプロジェクトには、eコマースシステムでよく使用される機能だけでなく、私のGo開発経験も盛り込まれています。 この記事は、Go の基礎を修了し、成熟したフレームワークに基づいて Web プロジェクトを開発する予定の学生に適しています。 GoFrameの紹介GoFrame は、PHP-Laravel や Java-SpringBoot に似た Go のエンタープライズ レベルの開発フレームワークであり、学習する価値のある Go フレームワークです。 以前、GoFrame を学ぶ価値がある理由を説明する記事を書きました: # PHP から Go への移行に最適なフレームワーク: GoFrame、# なぜ GoFrame の garray は PHP の array より優れているのでしょうか? これを読んで、GoFrame を高度な実用的なアプリケーションに使用するモチベーションを高めることができます。 経験の共有私はGoFrameを使って多くの商用プロジェクトを開発してきました。使い始めた当初は、使い勝手の悪い点が数多くありました。基本的には公式ドキュメントを読みながらプロジェクトを進めていきました。 より多くのプロジェクトに取り組んで、より多くの問題に遭遇するにつれて、最初に書いたコードが本当にひどかったことに気づきました。 このオープンソースコードは、必ずしもエレガントとは言えないかもしれませんが、非常に標準化されています。このコードに基づいて、機能モジュールを迅速に開発できるだけでなく、よく使用されるユーティリティクラスもカプセル化されています。 これは、誰もが Go を学習する際の効率を向上させるのに役立つはずです。 公式例公式ドキュメントでは、最新の v2.x バージョンに基づいた例が提供されており、次の観点からモノリシック API サービスを迅速に構築する方法が示されています。 - インターフェース定義
- ルーターの登録
- 継続的な管理
- コントローラの定義
- データベースアクセス
- ビジネスモデルを作成する
- サービスインターフェースを提供する
- ビジネスの実装
- インターフェーステスト
公式サンプルは非常に標準化されていますが、単純すぎます。基礎が弱い方は、まず公式サンプル[1]を練習し、その後に私のeコマースプロジェクトを練習することをお勧めします。 上級チュートリアル: 電子商取引のフロントエンドとバックエンドシステムエントリーレベルのeコマースシステムとして、一般的な機能が含まれています。以下では、習得できる技術的な知識に焦点を当てます。 - gtoken を使用してシングル サインオンを実装するにはどうすればよいですか?
- ミドルウェアをカスタマイズするにはどうすればいいですか?
- サービスをカスタマイズするには?
- ルーティング グループを定義してインターフェイス境界を明確にするにはどうすればよいですか?
- クラウド プラットフォームに画像をアップロードするにはどうすればよいですか?
- 検索条件を柔軟に設定するにはどうすればよいですか?
- プロジェクトでフロントエンド用とバックエンド用に 1 セットずつ、2 セットの API インターフェースを提供するにはどうすればよいですか?
- 自動コンパイルを実現するにはどうすればよいでしょうか?
- シェル スクリプトを使用して、1 回のクリックでプロジェクトをリモート サーバーにデプロイするにはどうすればよいですか?
注: 公式の GoFrame ドキュメントと例は、GoFrame フレームワークと CLI ツールをすぐに使い始めるのに役立ちますが、この記事の焦点ではありません。
この記事の焦点は、皆さんをさらに一歩進め、健全な標準に基づいたより複雑な商用プロジェクトを開発できるようにすることです。一緒に学びましょう!記事の最後に、このプロジェクトのGitHubアドレスと役立つドキュメントを共有します。 まずは目次を見てみましょう。全体的な構造 プロジェクト構造 アプリディレクトリに焦点を当てるアプリ ディレクトリは、私たちの開発の重要な部分です。 アプリディレクトリ 本当の戦いを始めよう注:簡潔な文章と分かりやすさを確保するため、コアコンセプトに関係のないコードは省略、または3つの縦線(.)を使用して簡略化しています。オープンソースプロジェクトのGitHubアドレスは、記事の最後に記載しています。
1. GTokenはシングルサインオンを可能にする1. バージョンを確認するまず、インストールされている gf のバージョンを確認する必要があります。これは、コマンド `gf version` を使用して確認できます。 バージョンを表示 注意: gtoken v1.5.0 は GoFrame v2.0.0 と完全に互換性があります。GoFrame v1.XX の場合は、GfToken v1.4.X または関連バージョンを使用してください。 バージョンに応じて適切な gtoken をインストールします。 2. gtokenの最新バージョンをインストールする github .com / goflyfox / gtoken を入手してください 3. 指定されたバージョンのgtokenをインストールするバージョン番号を指定するだけです: github .com / goflyfox / [email protected]を入手してください 2. カスタムミドルウェアgtoken ミドルウェアの作成を例にして、独自のミドルウェアの作成方法を説明します。 app/middleware ディレクトリに token.go という名前の新しいファイルを作成します。 gtoken ミドルウェアを作成する目的: - ユーザーのログインステータスをグローバルに検証する
- ログイン後、ユーザー名や ID などのユーザー情報がコンテキストに書き込まれ、グローバル アクセスが容易になります。
- 誰かがブラックリストに登録されているかどうかなどのアカウントチェックは、ミドルウェアで均一に実行される必要があります。
具体的な実装を見てみましょう。 パッケージミドルウェア
定数( CtxAccountId = "account_id" //トークンの取得 。 。 。 )
TokenInfo構造体型{ ID int 名前文字列 。 。 。 }
var GToken * gtoken .GfToken
varMiddlewareGToken = tokenMiddleware { }
タイプ tokenMiddleware 構造体{ }
func ( s * tokenMiddleware ) GetToken ( r * ghttp .Request ) { var tokenInfo トークン情報 トークン: = GToken.GetTokenData ( r ) err : = gconv .Struct ( token .GetString ( "data" ) , & tokenInfo ) err != nil の場合{ レスポンス.Auth ( r ) 戻る } //アカウントが凍結され、ブラックリストに登録されました tokenInfo.Status == 2 の場合 レスポンス.AuthBlack ( r ) 戻る } r .SetCtxVar ( CtxAccountId 、 tokenInfo .Id ) 。 。 。 r.Middleware.Next ( ) } 3. ミドルウェアを登録するクライアント側のルートを定義するために、app/system/frontend/ ディレクトリに router.go という名前の新しいファイルを作成します。 - まず、GToken のログインと登録のメソッドを記述します。
- 次に、ルート ファイルで group.Middleware() を使用して、カスタム ミドルウェアをルート グループに登録します。
- 注意: ログイン ステータスの検証を必要としないインターフェースは、group.Middleware(middleware.MiddlewareGToken.GetToken) の前に記述し、ログイン ステータスの検証を必要とするインターフェースは、group.Middleware(middleware.MiddlewareGToken.GetToken) の後に記述する必要があります。
パッケージフロントエンド
//フロントエンドプロジェクトのログイン 関数ログイン( ) { // gtokenを開始する ミドルウェア.GToken = & gtoken .GfToken { //すべてデフォルト設定を使用する //タイムアウト: gconv.Int ( g.Cfg ( ) .Get ( "gtoken.timeout" ) ) * gconv.Int ( gtime.M ) , // MaxRefresh : 60 * 1000 、 //単位: ミリ秒 ログイン後 1 分以内にリクエストまたは操作があった場合、トークンの有効期限がアクティブに更新されます。 キャッシュモード: 2 ログインパス: "/frontend/sso/login" 、 ログアウトパス: "/frontend/sso/logout" 、 AuthPaths : g .SliceStr { } , // AuthPaths : g .SliceStr { "/backend" } , AuthExcludePaths : g .SliceStr { } , GlobalMiddleware : true , //グローバルインターセプションを有効にする //マルチログイン: g .Config ( ) .GetBool ( "gtoken.multi-login" ) , LoginBeforeFunc : frontendLogin .FrontendLogin .Login 、 ログイン後関数: frontendLogin .FrontendLogin .LoginAfterFunc 、 LogoutAfterFunc : frontendLogin .FrontendLogin .Logout 、 AuthAfterFunc : frontendLogin .FrontendLogin .AuthAfterFunc 、 } ミドルウェア.GToken .Start ( ) }
function Init ( s * ghttp .Server ) { ログイン( ) s .Group ( "/frontend/ " , func ( group * ghttp .RouterGroup ) { //ログインは不要 ファイルをアップロード group .Group ( "upload/" 、 func ( group * ghttp .RouterGroup ) { グループ.POST ( "img/" 、アップロード.Upload .Img ) } )
//以下はログインが必要です。 グループ.Middleware (ミドルウェア.MiddlewareGToken .GetToken ) //ログインアカウント関連 グループ.グループ( "sso/" 、 func (グループ* ghttp .RouterGroup ) { グループ.POST ( "パスワード/更新" 、 frontendLogin .FrontendLogin .UpdatePassword ) } ) } ) } 4. カスタマイズされたサービス注意深いユーザーはすでに問題に気づいています: ルーティング ファイルのどこに frontendLogin.FrontendLogin.Login が定義されているのでしょうか? そうです、私たちはそれをサービスとして定義しました。 ログインや登録などの一般的な機能を抽出し、汎用サービスとして定義できます。 `app/service/frontendLogin` ディレクトリを作成し、その中に次のディレクトリを作成します。 - define.go: ログインと登録に必要な構造を定義するために使用されます。
- service.go: ログイン パスワードの検証などのビジネス ロジックを記述するために使用されます。
- api.go: このファイルは API を提供します。たとえば、frontendLogin.FrontendLogin.Login はここで定義されます。
define.go の簡略化された例パッケージフロントエンドログイン
RegisterReq構造体型{ 名前文字列 `json : "name" v : "required#ユーザー名は必須です" ` PassWord 文字列 `json : "password" v : "required-if:type,0|password#パスワードを渡す必要があります|パスワードは6文字から18文字の間でなければなりません" ` アバター文字列 `json : "avatar" ` 性別int `json : "sex" ` 署名文字列 `json : "sign" ` SecretAnswer 文字列 `json : "secret_answer" ` UserSalt文字列 `json : "user_salt,omitempty" ` }
AccessTokenRes構造体型{ AccessToken 文字列 `json : "access_token" ` //取得した認証情報 ExpiresIn int `json : "expires_in" ` //バウチャーの有効期間(秒) }
。 。 。 service.go の簡略化された例パッケージフロントエンドログイン
輸入( "コンテクスト" 。 。 。 )
var サービス=フロントエンドログインサービス{ }
フロントエンドログインサービス構造体{ }
。 。 。
//登録する func ( s * frontendLoginService ) Register ( ctx context .Context , req * RegisterReq ) ( err error ) { //ユーザー名が存在するかどうかを確認します count , err : = dao.UserInfo.Ctx ( ctx ) .Where ( "name" , req.Name ) .Count ( ) err != nil || count > 0の場合{ return gerror.New ( "ユーザー名は既に存在します。別のユーザー名でアカウントを登録してください。" ) }
ユーザーソルト: = grand.S ( 10 ) req .PassWord = library .EncryptPassword ( req .PassWord 、 UserSalt ) req.UserSalt =ユーザーソルト //新しいユーザーを追加する _ , err = dao .UserInfo .Ctx ( ctx ) .Insert ( req ) err != nil の場合{ エラーを返す } 戻る }
。 。 。 api.goの簡略化された例パッケージフロントエンドログイン
輸入( 「github.com/goflyfox/gtoken/gtoken」 。 。 。 )
var FrontendLogin = new ( frontendLogin )
フロントエンドログイン構造体{ }
//登録する func ( s * frontendLogin ) Register ( r * ghttp .Request ) { var data *レジスタ要求 err : = r .Parse ( & data )の場合; err != nil { 応答.ParamErr ( r , err ) } err : =サービス.Register ( r .Context ( ) ,データ) err != nil の場合{ response.JsonExit ( r , 0 , "登録に失敗しました" ) }それ以外{ レスポンス.SuccessWithData ( r , nil ) } } 。 。 。 さて、これで gtoken との統合が完了し、独自のミドルウェアとサービスを作成しました。 GToken の実装原理に興味のある方は、こちらの記事をお読みください: # ソースコードを読んでプロジェクトの問題を解決する: JWT を GToken に置き換えて SSO シングルサインオンを実装する 次に、前述のルーティング ファイルを詳しく見てみましょう。 4. ルーティング グループを定義し、インターフェイスの境界を明確にします。ルート管理をより明確かつ標準化するため、ルート管理にはグループ ルーティングを使用することをお勧めします。 ビジネスロジックに応じてルートグループを分割します。例えば、以下のコードでは、商品管理、記事管理、いいね管理が非常に明確になっています。 これにより、プロジェクトの反復時に指定されたルート グループ内で管理を継続できるようになり、インターフェイスの境界が明確に定義されます。 function Init ( s * ghttp .Server ) { ログイン( ) s .Group ( "/frontend/ " , func ( group * ghttp .RouterGroup ) { //商品 グループ.グループ( "goods/" , func ( group * ghttp .RouterGroup ) { グループ.POST ( "list/" 、商品.Goods .List ) グループ.POST ( "detail/" ,商品.Goods.Detail ) group .POST ( "category/" , goods .Goods .Category ) } ) //以下はログインが必要です。 グループ.Middleware (ミドルウェア.MiddlewareGToken .GetToken ) //記事 グループ.グループ( "article/" , func (グループ* ghttp .RouterGroup ) { グループ.POST ( "add/" 、記事.Article .Add ) グループ.POST ( "update/" 、記事.Article .Update ) グループ.POST ( "delete/" 、記事.Article .Delete ) group.POST ( "list/" , article.Article.List ) //すべての記事のリスト group.POST ( " my/list/" , article.Article.MyList ) //私の記事リスト group.POST ( "detail/" , article.Article.Detail ) //記事の詳細 } ) //のように group .Group ( "praise/" 、 func ( group * ghttp .RouterGroup ) { グループ.POST ( "add/" 、賞賛.賞賛.追加) グループ.POST ( "delete/" 、賞賛.賞賛.削除) グループ.POST ( "list/" 、賞賛.Praise .List ) } ) } ) }注:インターフェースの設計において、RESTful API仕様に厳密に従うのではなく、POSTリクエストのみを使用しました。厳密な制限はなく、API仕様、フレームワーク、プログラミング言語は問いません。ご自身に最適なものを選んでください。 5. クラウドプラットフォームに画像をアップロードするQiniu Cloud に画像をアップロードする場合を例に挙げてみましょう。 - まず、goframe が提供する `r.GetUploadFiles("file")` メソッドを使用して、ファイルをローカル マシン (サーバーにデプロイされている場合は、サーバー上のローカル マシン) にアップロードします。
- クラウド プラットフォームのプロンプトに従って、関連する AKSK を構成します。
- ローカルファイルパスをクラウドプラットフォームにアップロードする
- ローカルファイルを削除する
以下のキーコードはコメントアウトされています。AKSKおよびその他の構成情報は、/config/config.tomlファイルに設定されています。 パッケージのアップロード
var アップロード= uploadApi { }
uploadApi構造体{ }型
//アップロードはファイルを/ tmp にアップロードします。 func ( * uploadApi ) Img ( r * ghttp .Request ) { files : = r .GetUploadFiles ( "ファイル" ) dirPath : = "/tmp/" names , err : = files.Save ( dirPath , true ) err != nil の場合{ r .Response .WriteExit (エラー) }
for _ 、 name : =範囲名{ ローカルファイル: = dirPath +名前 バケット: = g .Cfg ( ) .GetString ( "qiniu.bucket" ) キー: =名前 accessKey : = g .Cfg ( ) .GetString ( "qiniu.accessKey" ) secretKey : = g .Cfg ( ) .GetString ( "qiniu.secretKey" )
putPolicy : =ストレージ.PutPolicy { スコープ:バケット、 } mac : = qbox .NewMac (アクセスキー,シークレットキー) upToken : = putPolicy .UploadToken ( mac )
cfg : =ストレージ.Config { } //対応するサーバールーム cfg .Zone = &ストレージ.ZoneHuabei // HTTPS ドメインを使用する必要がありますか? cfg.UseHTTPS = true //アップロードの高速化に CDN を使用する必要がありますか? cfg.UseCdnDomains = false
//フォームアップロードオブジェクトを構築する formUploader : =ストレージ.NewFormUploader ( & cfg ) ret : =ストレージ.PutRet { }
//オプションの設定 putExtra : =ストレージ.PutExtra { パラメータ: map [文字列]文字列{ } , }
err = formUploader .PutFile ( r .GetCtx ( ) 、 & ret 、 upToken 、 key 、 localFile 、 & putExtra ) err != nil の場合{ 応答.FailureWithData ( r , 0 , err , "" ) }
fmt .Println ( ret .Key , ret .Hash )
//ローカルファイルを削除する エラー= os.Remove (ローカルファイル) err != nil の場合{ g.Dump ( "ローカルファイルの削除に失敗しました:" , err ) } fmt.Println ( "ローカルファイルが正常に削除されました" , localFile )
//データを返す レスポンス.SuccessWithData ( r , g .Map { "url" : g .Cfg ( ) .GetString ( "qiniu.url" ) + ret .Key , } ) } } 6. 検索エンジンを科学的に記述するにはどうすればよいでしょうか?典型的な検索シナリオを説明しましょう。 複数の検索条件がありますが、いずれも必須ではありません。どの条件に合致したとしても、一致します。これをより科学的な方法で実現するにはどうすればよいでしょうか? 私の提案は、複雑な判断ロジックを必要とする宣言時の割り当てを回避し、クエリ条件を柔軟に設定するために、map の set メソッドのサポート機能を使用することです。 クエリ条件は packListCondition メソッドにカプセル化され、統一された管理と複数の場所での簡単な再利用が可能になります。 func ( s * goodsService ) List ( ctx context .Context , req * PageListReq ) ( res ListGoodsRes , err error ) { //マップをインスタンス化する whereCondition : = gmap.New ( ) //これは、参照型としてのマップの特性についてよく理解していることを示しています。関数はクエリ条件に値を割り当てます。 packListCondition ( req 、 whereCondition ) // map は参照型なので、packListCondition 関数内で代入演算が既に実行されており、戻り値を受け取る必要はありません。 count , err : = dao.GoodsInfo.Ctx ( ctx ) .Where ( whereCondition ) .Count ( ) err != nil の場合{ 戻る } res.Count =カウント err = dao .GoodsInfo .Ctx ( ctx ) .Where ( whereCondition ) .OrderDesc ( "id" ) .Page ( req .Page , req .Limit ) .Scan ( & res .List ) err != nil の場合{ 戻る } 戻る }
func packListCondition ( req * PageListReq 、 whereCondition * gmap .Map ) { //マップのセット機能のサポートを使用すると、宣言時に値を割り当てる必要がなくなり、必要なチェックが複雑になりすぎるのを防ぐことができます。 req.Keyword != ""の場合{ whereCondition .Set ( dao .GoodsInfo .Columns .DetailInfo + " like " , "%" + req .Keyword + "%" ) } req.Name != ""の場合{ whereCondition .Set ( dao .GoodsInfo .Columns .Name + " like " , "%" + req .Name + "%" ) } req.Brand != ""の場合{ whereCondition .Set ( dao .GoodsInfo .Columns .Brand + " like " , "%" + req .Brand + "%" ) } } 7. 2セットのAPIインターフェースを提供する全体を理解するために、ディレクトリ構造をもう一度見てみましょう。 - app/system ディレクトリは、フロントエンド システムとバックエンド システムの両方を 1 つのプロジェクト内で同時に開発し、コードの再利用性を向上させるために作成されました。
- app/system ディレクトリを除く他のすべてのディレクトリは、goframe gf ツールを使用して生成されました。
- したがって、2 セットの API インターフェースを提供するプロジェクトを実装する際の中核となるのは、フロントエンド プロジェクトとバックエンド プロジェクトの両方に必要な API インターフェースを同時に提供しながら、単一のプロジェクト内で 2 つのサービスを開始する方法です。
私が行ったことは次のとおりです。main.go エントリ ファイルで、フロントエンド プロジェクトとバックエンド プロジェクトのルーティング ファイルをそれぞれ初期化し、サービスを開始しました。 パッケージメイン
輸入( 「github.com/gogf/gf/frame/g」 「ショップ/アプリ/ミドルウェア」 「ショップ/アプリ/システム/バックエンド」 「ショップ/アプリ/システム/フロントエンド」 「ショップ/ブート」 「ショップ/ルーター」 )
関数main ( ) { s : = g .Server ( ) s .Use (ミドルウェア.Cors .CORS ) //バックエンドプロジェクト backend.Init ( s ) //フロントエンドプロジェクト frontend.Init ( s ) s.実行( ) } 基本的なアプローチは次のとおりです。フロントエンドプロジェクトとバックエンドプロジェクトのルーティングは、インターフェースがどのプラットフォームに属するかを区別するためのルーティンググループに基づいています。インターフェースの内部ロジックは、再利用可能な場合は再利用されます。再利用できず、独立した機能である場合は、システムのバックエンドまたはフロントエンドの下で個別に開発されます。 フロントエンドインターフェースルーティングファイル function Init ( s * ghttp .Server ) { s .Group ( "/frontend/ " , func ( group * ghttp .RouterGroup ) { 。 。 。 } }バックエンドAPIルーティングファイル function Init ( s * ghttp .Server ) { s .Group ( "/backend/ " , func ( group * ghttp .RouterGroup ) { 。 。 。 } } ヒント: 単一のプロジェクトを開発することだけが要件である場合は、システム ディレクトリを削除し、ネイティブ ディレクトリで直接開発することができます。
この時点で、プロジェクトの全体的なセットアップと開発は完了しました。ご興味のある方は、GitHubでオープンソース化したプロジェクトのソースコードにスターを付けたり、フォークしたりすることができます。GitHub EコマースフロントエンドおよびバックエンドシステムAPI(GoFrame上に構築)[2] 8. 自動コンパイル自動コンパイルはGoFrameに組み込まれているため、air自動コンパイルプラグインをインストールする必要はありません。以下のコマンドを実行するだけで自動コンパイルを実行できます。 gf 実行main.go 効果は以下のとおりです。 実行効果 最後に、シェル スクリプトを記述して、プロジェクトをリモート サーバーにワンクリックで展開する機能を実装しました。 9. ワンクリックスクリプトの展開 RED_COLOR = '\E[1;31m' #赤 GREEN_COLOR = '\E[1;32m' #緑 YELOW_COLOR = '\E[1;33m' #黄色 BLUE_COLOR = '\E[1;34m' #青 ピンク= '\E[1;35m' #ピンク RES = '\E[0m'
echo -e "${GREEN_COLOR}****GoFrame 上に構築された電子商取引のフロントエンドおよびバックエンド API システム: 自動デプロイメントを開始しています****${RES}\n\n"
echo -e "${YELOW_COLOR}---step1:コードのマージ---${RES}" git pull origin マスター echo -e "${BLUE_COLOR} コードのマージが成功しました ${RES}\n"
echo -e "${YELOW_COLOR}---ステップ2:コンパイル---${RES}" ビルドする echo -e "${BLUE_COLOR} のコンパイルが完了しました ${RES}\n"
echo -e "${YELOW_COLOR}---ステップ3: 権限の変更---${RES}" chmod - R 777ショップ echo -e "${BLUE_COLOR} 権限の変更が完了しました ${RES}\n"
echo -e "${YELOW_COLOR}---ステップ4: プロセスを終了して実行---${RES}" i1 = $ ( ps - ef | grep - E "shop" | grep - v grep | awk '{print $2}' ) echo -e "${BLUE_COLOR} はプロセス $i1${RES} を強制終了します\n" キル- 9 $i1 && nohup ./shop >/ dev / null 2 >& 1 & i2 = $ ( ps - ef | grep - E "shop" | grep - v grep | awk '{print $2}' ) echo -e "${GREEN_COLOR}**** デプロイメントが成功しました。デプロイメント プロセス ID は: $i2${RES}****" 学習教材以下に、練習にお勧めする学習教材をいくつか紹介します。 GitHub: GoFrame上に構築されたEコマースフロントエンドおよびバックエンドシステムAPI [3] GoFrame学習コラム[4] GoFrame公式ドキュメント[5] Github: GoFrame入門公式サンプルプロジェクト [6] 要約この記事では、GoFrameフレームワークをベースとしたeコマースシステムのフロントエンドおよびバックエンドAPIの構築方法を説明します。ログイン用のgtokenの統合方法、ミドルウェアとサービスのカスタマイズ方法、ルーティンググループの定義方法、クラウドプラットフォームへのファイルのアップロード方法、開発中の自動コンパイルの実現方法、そして開発完了後にワンクリックでプロジェクトをリモートサーバーにデプロイする方法を紹介します。 ぜひ皆さんも試してみて、コメント欄で気軽に議論してください。 バージョンについてこの記事では、GoFrame v1.16 をベースにしたオープンソース プロジェクトを紹介します: https://github.com/wangzhongyang007/goframe-shop/ GoFrame の最新バージョンは現在 v2.4 で、この最新バージョンをベースにした電子商取引実践プロジェクトもオープンソース化しています: https://github.com/wangzhongyang007/goframe-shop-v2 皆様に、これら 2 つのオープンソース プロジェクトにスターを付けていただくことを歓迎します。また、最適化に関するご提案も歓迎します。 関連資料[1] 基礎が弱い人は、まず公式の例を練習してみましょう: https://goframe.org/pages/viewpage.action?pageId=57183756 [2] GitHub上のGoFrame上に構築されたEコマースフロントエンドおよびバックエンドシステムAPI:https://github.com/wangzhongyang007/goframe-shop/ [3] GitHub: GoFrame上に構築されたEコマースフロントエンドおよびバックエンドシステムAPI: https://github.com/wangzhongyang007/goframe-shop/tree/master [4] GoFrame学習コラム:https://juejin.cn/column/7146133427706658847 [5] GoFrame公式ドキュメント: https://goframe.org/pages/viewpage.action?pageId=1114119 [6] Github: 公式GoFrame入門サンプルプロジェクト: https://github.com/gogf/gf-demo-user この記事は、WeChat公式アカウント「プログラマーのレベルアップとモンスターとの闘いの旅」(著者:王中洋)からの転載です。以下のQRコードをスキャンしてアカウントをフォローできます。 この記事を転載する場合は、WeChat公式アカウント「プログラマーのレベルアップとモンスターとの戦いの旅」までご連絡ください。 |