{"id":1099,"date":"2026-08-17T07:18:39","date_gmt":"2026-08-17T07:18:39","guid":{"rendered":"https:\/\/www.devopsschool.com\/tutorials\/?p=1099"},"modified":"2026-08-17T07:18:41","modified_gmt":"2026-08-17T07:18:41","slug":"go-tutorials-modules-packages-subpackages-submodules-and-workspaces","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/tutorials\/go-tutorials-modules-packages-subpackages-submodules-and-workspaces\/","title":{"rendered":"Go Tutorials: Modules, Packages, Subpackages, Submodules, and Workspaces"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">This tutorial gives you one complete mental model for:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Module<\/li>\n\n\n\n<li>Package<\/li>\n\n\n\n<li>Subpackage<\/li>\n\n\n\n<li>Submodule<\/li>\n\n\n\n<li><code>go.mod<\/code><\/li>\n\n\n\n<li><code>go.work<\/code><\/li>\n\n\n\n<li>Local development<\/li>\n\n\n\n<li>Production\/release setup<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The most important idea is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Repository\n\u2502\n\u2514\u2500\u2500 Module\n    \u2502\n    \u251c\u2500\u2500 Package\n    \u251c\u2500\u2500 Package\n    \u2502   \u2514\u2500\u2500 Nested Package\n    \u2514\u2500\u2500 Package\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And sometimes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Repository\n\u2502\n\u251c\u2500\u2500 Root Module\n\u2502\n\u251c\u2500\u2500 Submodule\n\u251c\u2500\u2500 Submodule\n\u2514\u2500\u2500 Submodule\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">These two designs are very different.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">1. What is a Go module?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A <strong>module<\/strong> is a collection of Go packages managed together.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A module is identified by:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go.mod\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>shop\/\n\u251c\u2500\u2500 go.mod\n\u251c\u2500\u2500 main.go\n\u251c\u2500\u2500 payment\/\n\u251c\u2500\u2500 order\/\n\u2514\u2500\u2500 customer\/\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Here:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>shop\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">is one Go module because it contains:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>shop\/go.mod\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example <code>go.mod<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module example.com\/shop\n\ngo 1.26\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The line:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module example.com\/shop\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">defines the module&#8217;s import path.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">2. What is a Go package?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A <strong>package<\/strong> is a group of related <code>.go<\/code> files inside the same directory.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>shop\/\n\u251c\u2500\u2500 go.mod\n\u251c\u2500\u2500 main.go\n\u2502\n\u251c\u2500\u2500 payment\/\n\u2502   \u2514\u2500\u2500 payment.go\n\u2502\n\u251c\u2500\u2500 order\/\n\u2502   \u2514\u2500\u2500 order.go\n\u2502\n\u2514\u2500\u2500 customer\/\n    \u2514\u2500\u2500 customer.go\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">There is only one module:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>example.com\/shop\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">But there are multiple packages:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>main\npayment\norder\ncustomer\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ payment\/payment.go\n\npackage payment\n\nimport \"fmt\"\n\nfunc Pay() {\n    fmt.Println(\"Payment completed\")\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You can call it from <code>main.go<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nimport \"example.com\/shop\/payment\"\n\nfunc main() {\n    payment.Pay()\n}\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">3. Module vs package<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">The easiest distinction is:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Module<\/th><th>Package<\/th><\/tr><\/thead><tbody><tr><td>Collection of packages<\/td><td>Collection of <code>.go<\/code> files<\/td><\/tr><tr><td>Has <code>go.mod<\/code><\/td><td>Normally does not have <code>go.mod<\/code><\/td><\/tr><tr><td>Dependency\/version boundary<\/td><td>Code organization boundary<\/td><\/tr><tr><td>Can contain many packages<\/td><td>Lives inside a module<\/td><\/tr><tr><td>Example: <code>example.com\/shop<\/code><\/td><td>Example: <code>payment<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Think:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Module\n\u2502\n\u251c\u2500\u2500 Package\n\u251c\u2500\u2500 Package\n\u2514\u2500\u2500 Package\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>shop                   \u2190 Module\n\u2502\n\u251c\u2500\u2500 payment            \u2190 Package\n\u251c\u2500\u2500 order              \u2190 Package\n\u2514\u2500\u2500 customer           \u2190 Package\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">4. Is there a subpackage in Go?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Yes, you can organize packages inside other directories.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>shop\/\n\u251c\u2500\u2500 go.mod\n\u2502\n\u2514\u2500\u2500 customer\/\n    \u251c\u2500\u2500 customer.go\n    \u2502\n    \u2514\u2500\u2500 validation\/\n        \u2514\u2500\u2500 validation.go\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Humans may call:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>customer\/validation\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">a <strong>subpackage<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But Go does not give it any special parent-child relationship.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Go sees:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>example.com\/shop\/customer\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">and:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>example.com\/shop\/customer\/validation\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">as two separate packages.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ customer\/validation\/validation.go\n\npackage validation\n\nfunc IsValid(name string) bool {\n    return name != \"\"\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Use it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nimport (\n    \"fmt\"\n\n    \"example.com\/shop\/customer\/validation\"\n)\n\nfunc main() {\n    result := validation.IsValid(\"Rajesh\")\n\n    fmt.Println(result)\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Output:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>true\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Important rule:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Directory = Package\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Usually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>customer\/\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">is one package.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>customer\/validation\/\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">is another package.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">5. What is a submodule?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Go does not have a special language feature called <code>submodule<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But you can create a <strong>nested module<\/strong> inside another repository.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If a directory contains its own:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go.mod\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">it becomes a separate module.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>shop\/\n\u2502\n\u251c\u2500\u2500 go.mod\n\u251c\u2500\u2500 main.go\n\u2502\n\u251c\u2500\u2500 payment\/\n\u2502   \u251c\u2500\u2500 go.mod\n\u2502   \u2514\u2500\u2500 payment.go\n\u2502\n\u251c\u2500\u2500 order\/\n\u2502   \u251c\u2500\u2500 go.mod\n\u2502   \u2514\u2500\u2500 order.go\n\u2502\n\u2514\u2500\u2500 customer\/\n    \u251c\u2500\u2500 go.mod\n    \u2514\u2500\u2500 customer.go\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now you have four modules.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>shop\npayment\norder\ncustomer\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You can think of:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>payment\norder\ncustomer\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">as submodules or nested modules.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">6. Root module + 3 submodules example<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">We will build:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>shop\/\n\u2502\n\u251c\u2500\u2500 go.mod\n\u251c\u2500\u2500 main.go\n\u2502\n\u251c\u2500\u2500 payment\/\n\u2502   \u251c\u2500\u2500 go.mod\n\u2502   \u2514\u2500\u2500 payment.go\n\u2502\n\u251c\u2500\u2500 order\/\n\u2502   \u251c\u2500\u2500 go.mod\n\u2502   \u2514\u2500\u2500 order.go\n\u2502\n\u2514\u2500\u2500 customer\/\n    \u251c\u2500\u2500 go.mod\n    \u2514\u2500\u2500 customer.go\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">7. Create root module<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Create project:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir shop\ncd shop\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Create root module:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go mod init example.com\/shop\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This creates:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go.mod\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module example.com\/shop\n\ngo 1.26\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">8. Create payment submodule<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir payment\ncd payment\ngo mod init example.com\/shop\/payment\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Create:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>payment.go\n<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>package payment\n\nimport \"fmt\"\n\nfunc Pay() {\n    fmt.Println(\"Payment completed\")\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Your payment module now looks like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>payment\/\n\u251c\u2500\u2500 go.mod\n\u2514\u2500\u2500 payment.go\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>payment\/go.mod<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module example.com\/shop\/payment\n\ngo 1.26\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Go back:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd ..\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">9. Create order submodule<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir order\ncd order\ngo mod init example.com\/shop\/order\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Create:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ order.go\n\npackage order\n\nimport \"fmt\"\n\nfunc CreateOrder() {\n    fmt.Println(\"Order created\")\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>order\/go.mod<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module example.com\/shop\/order\n\ngo 1.26\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Go back:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd ..\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">10. Create customer submodule<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir customer\ncd customer\ngo mod init example.com\/shop\/customer\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Create:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ customer.go\n\npackage customer\n\nimport \"fmt\"\n\nfunc CreateCustomer() {\n    fmt.Println(\"Customer created\")\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>customer\/go.mod<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module example.com\/shop\/customer\n\ngo 1.26\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Go back:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd ..\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">11. Root main.go<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Create:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>shop\/main.go\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nimport (\n    \"example.com\/shop\/customer\"\n    \"example.com\/shop\/order\"\n    \"example.com\/shop\/payment\"\n)\n\nfunc main() {\n\n    customer.CreateCustomer()\n\n    order.CreateOrder()\n\n    payment.Pay()\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Notice:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>customer.CreateCustomer()\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">means:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package.function\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Similarly:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>order.CreateOrder()\npayment.Pay()\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">12. Why this does not immediately work<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">You now have four independent modules:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>example.com\/shop\n\nexample.com\/shop\/payment\n\nexample.com\/shop\/order\n\nexample.com\/shop\/customer\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The root module does not automatically know that:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\/payment\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">should represent:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>example.com\/shop\/payment\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is where <code>go.work<\/code> becomes useful.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">13. What is go.work?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\"><code>go.work<\/code> defines a <strong>Go workspace<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A workspace tells Go:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Use these local modules together while I am developing.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">From the root:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go work init .\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go work use .\/payment\ngo work use .\/order\ngo work use .\/customer\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>shop\/\n\u251c\u2500\u2500 go.work\n\u251c\u2500\u2500 go.mod\n\u251c\u2500\u2500 main.go\n\u251c\u2500\u2500 payment\/\n\u251c\u2500\u2500 order\/\n\u2514\u2500\u2500 customer\/\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Your <code>go.work<\/code> will look approximately like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go 1.26\n\nuse (\n    .\n    .\/customer\n    .\/order\n    .\/payment\n)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Meaning:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Use root module\nUse customer module\nUse order module\nUse payment module\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">14. Run the application locally<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go run .\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Output:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Customer created\nOrder created\nPayment completed\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The flow is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>main.go\n   \u2502\n   \u251c\u2500\u2500 customer.CreateCustomer()\n   \u2502             \u2502\n   \u2502             \u2193\n   \u2502      customer\/customer.go\n   \u2502\n   \u251c\u2500\u2500 order.CreateOrder()\n   \u2502             \u2502\n   \u2502             \u2193\n   \u2502        order\/order.go\n   \u2502\n   \u2514\u2500\u2500 payment.Pay()\n                 \u2502\n                 \u2193\n          payment\/payment.go\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">15. Why go.work is useful<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Imagine you&#8217;re developing all modules together.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You modify:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>payment\/payment.go\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then immediately:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go run .\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">uses your local changed version.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You don&#8217;t have to publish:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>payment v1.0.1\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">every time you make a small change.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go.work\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">is mainly useful for:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>local multi-module development\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">16. Development architecture<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">During development:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>                   shop\n                    \u2502\n                 main.go\n                    \u2502\n       \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n       \u2502            \u2502             \u2502\n       \u2193            \u2193             \u2193\n   customer       order        payment\n       \u2502            \u2502             \u2502\n       \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                    \u2502\n                  go.work\n                    \u2502\n              Local directories\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The root app imports:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import (\n    \"example.com\/shop\/customer\"\n    \"example.com\/shop\/order\"\n    \"example.com\/shop\/payment\"\n)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">But Go actually uses:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\/customer\n.\/order\n.\/payment\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">because of <code>go.work<\/code>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">17. Production: what changes?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">For production, normally dependencies should come from:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go.mod\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">instead of depending on your local workspace.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Production should generally use known module versions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module github.com\/company\/shop\n\ngo 1.26\n\nrequire (\n    github.com\/company\/shop\/customer v1.0.0\n    github.com\/company\/shop\/order v1.0.0\n    github.com\/company\/shop\/payment v1.0.0\n)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now your dependencies are explicit:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>customer v1.0.0\norder    v1.0.0\npayment  v1.0.0\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">18. Development vs production<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Development<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>main.go\n   \u2502\n   \u2193\ngo.work\n   \u2502\n   \u251c\u2500\u2500 .\/customer\n   \u251c\u2500\u2500 .\/order\n   \u2514\u2500\u2500 .\/payment\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Production<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>main.go\n   \u2502\n   \u2193\ngo.mod\n   \u2502\n   \u251c\u2500\u2500 customer v1.0.0\n   \u251c\u2500\u2500 order v1.0.0\n   \u2514\u2500\u2500 payment v1.0.0\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Simple rule:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Development \u2192 local code \u2192 go.work\n\nProduction \u2192 released\/versioned code \u2192 go.mod\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">19. Real GitHub-style module example<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose your Git repository is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>github.com\/company\/shop\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Root module:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module github.com\/company\/shop\n\ngo 1.26\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Payment module:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module github.com\/company\/shop\/payment\n\ngo 1.26\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Order module:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module github.com\/company\/shop\/order\n\ngo 1.26\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Customer module:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module github.com\/company\/shop\/customer\n\ngo 1.26\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Your <code>main.go<\/code> becomes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nimport (\n    \"github.com\/company\/shop\/customer\"\n    \"github.com\/company\/shop\/order\"\n    \"github.com\/company\/shop\/payment\"\n)\n\nfunc main() {\n    customer.CreateCustomer()\n    order.CreateOrder()\n    payment.Pay()\n}\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">20. Publishing nested modules<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Because each subdirectory is a separate module, each module can have its own version.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example versions:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>payment v1.0.0\norder v1.0.0\ncustomer v1.0.0\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For nested modules in a single Git repository, tags are commonly:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git tag payment\/v1.0.0\ngit tag order\/v1.0.0\ngit tag customer\/v1.0.0\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Push tags:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git push --tags\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then the root module can depend on those versions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module github.com\/company\/shop\n\ngo 1.26\n\nrequire (\n    github.com\/company\/shop\/customer v1.0.0\n    github.com\/company\/shop\/order v1.0.0\n    github.com\/company\/shop\/payment v1.0.0\n)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then build:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go mod tidy\ngo build .\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">21. What does go mod tidy do?<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>go mod tidy\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">makes sure:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go.mod\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">and:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go.sum\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">contain the dependencies your source code actually uses.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Think:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Source code imports\n        \u2193\n   go mod tidy\n        \u2193\n   Clean go.mod\n   Clean go.sum\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">22. What is go.sum?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\"><code>go.sum<\/code> records checksums for downloaded module dependencies.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example structure:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>shop\/\n\u251c\u2500\u2500 go.mod\n\u251c\u2500\u2500 go.sum\n\u2514\u2500\u2500 main.go\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You normally commit:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go.mod\ngo.sum\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">to Git.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>go.sum<\/code> helps Go verify that dependency contents have not unexpectedly changed.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">23. Important: You usually do NOT need submodules<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">This is the most important practical advice.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For most applications, this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>shop\/\n\u251c\u2500\u2500 go.mod\n\u251c\u2500\u2500 main.go\n\u251c\u2500\u2500 payment\/\n\u2502   \u2514\u2500\u2500 payment.go\n\u251c\u2500\u2500 order\/\n\u2502   \u2514\u2500\u2500 order.go\n\u2514\u2500\u2500 customer\/\n    \u2514\u2500\u2500 customer.go\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">is better.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You have:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>1 Module\n\u2502\n\u251c\u2500\u2500 payment package\n\u251c\u2500\u2500 order package\n\u2514\u2500\u2500 customer package\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">There is only one:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go.mod\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">No <code>go.work<\/code> needed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">No separate versions needed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">No separate releases needed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">No dependency complexity.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">24. Recommended normal project<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Create:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir shop\ncd shop\n\ngo mod init example.com\/shop\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Structure:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>shop\/\n\u251c\u2500\u2500 go.mod\n\u251c\u2500\u2500 main.go\n\u2502\n\u251c\u2500\u2500 payment\/\n\u2502   \u2514\u2500\u2500 payment.go\n\u2502\n\u251c\u2500\u2500 order\/\n\u2502   \u2514\u2500\u2500 order.go\n\u2502\n\u2514\u2500\u2500 customer\/\n    \u2514\u2500\u2500 customer.go\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">25. payment package<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>package payment\n\nimport \"fmt\"\n\nfunc Pay() {\n    fmt.Println(\"Payment completed\")\n}\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">26. order package<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>package order\n\nimport \"fmt\"\n\nfunc CreateOrder() {\n    fmt.Println(\"Order created\")\n}\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">27. customer package<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>package customer\n\nimport \"fmt\"\n\nfunc CreateCustomer() {\n    fmt.Println(\"Customer created\")\n}\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">28. Root main.go<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nimport (\n    \"example.com\/shop\/customer\"\n    \"example.com\/shop\/order\"\n    \"example.com\/shop\/payment\"\n)\n\nfunc main() {\n\n    customer.CreateCustomer()\n\n    order.CreateOrder()\n\n    payment.Pay()\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go run .\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Output:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Customer created\nOrder created\nPayment completed\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Notice something important:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The calling code looks almost identical to the multi-module example.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>payment.Pay()\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">doesn&#8217;t tell you whether <code>payment<\/code> is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>a package inside the module\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">or:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>a completely separate module\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The import path and module configuration determine that.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">29. Single module vs multiple modules<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Single-module design<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>shop\/\n\u2502\n\u251c\u2500\u2500 go.mod\n\u2502\n\u251c\u2500\u2500 payment\/\n\u2502\n\u251c\u2500\u2500 order\/\n\u2502\n\u2514\u2500\u2500 customer\/\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Relationship:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>shop module\n   \u2502\n   \u251c\u2500\u2500 payment package\n   \u251c\u2500\u2500 order package\n   \u2514\u2500\u2500 customer package\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Best for:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Normal applications<\/li>\n\n\n\n<li>APIs<\/li>\n\n\n\n<li>Web applications<\/li>\n\n\n\n<li>CLI tools<\/li>\n\n\n\n<li>Backend services<\/li>\n\n\n\n<li>Small and medium projects<\/li>\n\n\n\n<li>Packages released together<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">30. Multi-module design<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>shop\/\n\u2502\n\u251c\u2500\u2500 go.mod\n\u2502\n\u251c\u2500\u2500 payment\/\n\u2502   \u2514\u2500\u2500 go.mod\n\u2502\n\u251c\u2500\u2500 order\/\n\u2502   \u2514\u2500\u2500 go.mod\n\u2502\n\u2514\u2500\u2500 customer\/\n    \u2514\u2500\u2500 go.mod\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Relationship:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Repository\n\u2502\n\u251c\u2500\u2500 shop module\n\u251c\u2500\u2500 payment module\n\u251c\u2500\u2500 order module\n\u2514\u2500\u2500 customer module\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Best when modules need:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Independent versions<\/li>\n\n\n\n<li>Independent releases<\/li>\n\n\n\n<li>Independent dependencies<\/li>\n\n\n\n<li>Independent reuse<\/li>\n\n\n\n<li>Separate ownership<\/li>\n\n\n\n<li>Separate lifecycle<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">31. Comparison<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Feature<\/th><th>Package<\/th><th>Subpackage<\/th><th>Submodule<\/th><\/tr><\/thead><tbody><tr><td>Separate directory<\/td><td>Usually<\/td><td>Yes<\/td><td>Yes<\/td><\/tr><tr><td>Own <code>go.mod<\/code><\/td><td>No<\/td><td>No<\/td><td>Yes<\/td><\/tr><tr><td>Independent version<\/td><td>No<\/td><td>No<\/td><td>Yes<\/td><\/tr><tr><td>Independent dependencies<\/td><td>No<\/td><td>No<\/td><td>Yes<\/td><\/tr><tr><td>Importable<\/td><td>Yes<\/td><td>Yes<\/td><td>Yes<\/td><\/tr><tr><td>Part of parent module<\/td><td>Yes<\/td><td>Yes<\/td><td>No<\/td><\/tr><tr><td>Common in normal apps<\/td><td>Very common<\/td><td>Common<\/td><td>Less common<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">32. go.mod vs go.work<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th><code>go.mod<\/code><\/th><th><code>go.work<\/code><\/th><\/tr><\/thead><tbody><tr><td>Defines a module<\/td><td>Defines a workspace<\/td><\/tr><tr><td>Required for modules<\/td><td>Optional<\/td><\/tr><tr><td>Declares dependencies<\/td><td>Groups local modules<\/td><\/tr><tr><td>Used for builds\/releases<\/td><td>Mostly useful for local multi-module development<\/td><\/tr><tr><td>Usually committed<\/td><td>Often developer\/workspace-specific<\/td><\/tr><tr><td>Contains <code>require<\/code><\/td><td>Contains <code>use<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Example <code>go.mod<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module github.com\/company\/shop\n\ngo 1.26\n\nrequire github.com\/company\/payment v1.0.0\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example <code>go.work<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go 1.26\n\nuse (\n    .\n    .\/payment\n)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Mental model:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go.mod\n\n\"What does this module depend on?\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">versus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go.work\n\n\"Which local modules am I developing together?\"\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">33. What does import actually import?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import \"example.com\/shop\/payment\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Go reads this as an <strong>import path<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>payment.Pay()\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">means:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package identifier\n        .\nexported function\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">So:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>payment.Pay()\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>payment package\n      \u2193\nPay function\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">34. Why is Pay capitalized?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">In Go:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>func Pay()\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">starts with capital <code>P<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Therefore it is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>exported\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Other packages can call it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>func pay()\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">starts with lowercase.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Therefore it is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>unexported\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Only code inside the same package can call it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package payment\n\nfunc Pay() {\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Can be called:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>payment.Pay()\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">But:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package payment\n\nfunc pay() {\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">cannot be called from <code>main<\/code>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">35. Package name vs module path<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Consider:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module example.com\/shop\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">and:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>payment\/payment.go\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package payment\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The full import path becomes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>example.com\/shop\/payment\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Break it down:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>example.com\/shop         \/ payment\n       \u2502                      \u2502\n    Module                 Package\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">36. Complete hierarchy<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">The clean mental hierarchy is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Git Repository\n      \u2502\n      \u251c\u2500\u2500 Module\n      \u2502     \u2502\n      \u2502     \u251c\u2500\u2500 Package\n      \u2502     \u2502     \u2502\n      \u2502     \u2502     \u251c\u2500\u2500 File\n      \u2502     \u2502     \u2502    \u251c\u2500\u2500 Function\n      \u2502     \u2502     \u2502    \u251c\u2500\u2500 Struct\n      \u2502     \u2502     \u2502    \u251c\u2500\u2500 Method\n      \u2502     \u2502     \u2502    \u2514\u2500\u2500 Interface\n      \u2502     \u2502\n      \u2502     \u2514\u2500\u2500 Package\n      \u2502\n      \u2514\u2500\u2500 Optional separate Module\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>shop repository\n\u2502\n\u251c\u2500\u2500 go.mod\n\u2502\n\u251c\u2500\u2500 payment\/\n\u2502   \u2514\u2500\u2500 payment.go\n\u2502        \u2502\n\u2502        \u2514\u2500\u2500 Pay()\n\u2502\n\u2514\u2500\u2500 order\/\n    \u2514\u2500\u2500 order.go\n         \u2502\n         \u2514\u2500\u2500 CreateOrder()\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">37. Root module terminology<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>shop\/\n\u251c\u2500\u2500 go.mod\n\u2514\u2500\u2500 payment\/\n    \u2514\u2500\u2500 payment.go\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>shop<\/code> is the module root because:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go.mod\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">exists there.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Everything below it normally belongs to the same module until Go encounters another <code>go.mod<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>shop\/\n\u251c\u2500\u2500 go.mod            \u2190 Module A\n\u2502\n\u251c\u2500\u2500 customer\/         \u2190 Module A\n\u251c\u2500\u2500 payment\/          \u2190 Module A\n\u2502\n\u2514\u2500\u2500 tools\/\n    \u251c\u2500\u2500 go.mod        \u2190 Module B begins here\n    \u2514\u2500\u2500 tool.go\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The second <code>go.mod<\/code> creates a new module boundary.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is a very important rule:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">A new <code>go.mod<\/code> means a new module boundary.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">38. The easiest way to recognize everything<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Look for:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go.mod\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you see:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>one go.mod\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">you probably have:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>one module + many packages\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you see:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>four go.mod files\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">you have:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>four modules\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>shop\/\n\u251c\u2500\u2500 go.mod                 \u2190 Module 1\n\u251c\u2500\u2500 payment\/\n\u2502   \u2514\u2500\u2500 payment.go\n\u251c\u2500\u2500 order\/\n\u2502   \u2514\u2500\u2500 order.go\n\u2514\u2500\u2500 customer\/\n    \u2514\u2500\u2500 customer.go\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">= <strong>1 module<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Versus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>shop\/\n\u251c\u2500\u2500 go.mod                 \u2190 Module 1\n\u251c\u2500\u2500 payment\/\n\u2502   \u2514\u2500\u2500 go.mod             \u2190 Module 2\n\u251c\u2500\u2500 order\/\n\u2502   \u2514\u2500\u2500 go.mod             \u2190 Module 3\n\u2514\u2500\u2500 customer\/\n    \u2514\u2500\u2500 go.mod             \u2190 Module 4\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">= <strong>4 modules<\/strong><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">39. One very useful rule<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Ask:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Do these components need independent versions?<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">If the answer is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>No\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">use packages.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>1 module\n+\nmany packages\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If the answer is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Yes\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">consider multiple modules.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>multiple go.mod files\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">40. When should I use a package?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Use packages when you simply want to organize code.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>shop\/\n\u251c\u2500\u2500 payment\/\n\u251c\u2500\u2500 order\/\n\u251c\u2500\u2500 customer\/\n\u251c\u2500\u2500 database\/\n\u251c\u2500\u2500 config\/\n\u2514\u2500\u2500 logger\/\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">They are different areas of your application.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You do not need:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>payment v1.0\norder v2.0\ncustomer v1.5\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">So packages are enough.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">41. When should I use a submodule?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A separate module may make sense if <code>payment<\/code> is essentially an independent library.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>payment\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">is used by:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>shop\nmobile-backend\nbilling-system\nsubscription-system\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And it needs its own releases:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>v1.0.0\nv1.1.0\nv2.0.0\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then making <code>payment<\/code> its own module can make sense.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">42. Example real-world architecture<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Normal application:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ecommerce\/\n\u251c\u2500\u2500 go.mod\n\u251c\u2500\u2500 cmd\/\n\u2502   \u2514\u2500\u2500 server\/\n\u2502       \u2514\u2500\u2500 main.go\n\u2502\n\u251c\u2500\u2500 customer\/\n\u251c\u2500\u2500 order\/\n\u251c\u2500\u2500 payment\/\n\u251c\u2500\u2500 inventory\/\n\u251c\u2500\u2500 notification\/\n\u2514\u2500\u2500 database\/\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>1 module\n+\nmany packages\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Usually this is what you should start with.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">43. Multi-module architecture<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">For a large library repository:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>platform\/\n\u251c\u2500\u2500 go.work\n\u2502\n\u251c\u2500\u2500 auth\/\n\u2502   \u2514\u2500\u2500 go.mod\n\u2502\n\u251c\u2500\u2500 database\/\n\u2502   \u2514\u2500\u2500 go.mod\n\u2502\n\u251c\u2500\u2500 messaging\/\n\u2502   \u2514\u2500\u2500 go.mod\n\u2502\n\u2514\u2500\u2500 telemetry\/\n    \u2514\u2500\u2500 go.mod\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now each library can evolve independently.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">During development:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go.work\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">connects them.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For releases:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>auth v1.2.0\ndatabase v3.0.0\nmessaging v2.1.0\ntelemetry v1.4.0\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">44. Golden rule<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">For beginners:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Start with ONE module.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then create many packages:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module\n\u2502\n\u251c\u2500\u2500 package\n\u251c\u2500\u2500 package\n\u251c\u2500\u2500 package\n\u2514\u2500\u2500 package\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Only introduce more modules when you actually need:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>independent versioning\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">or:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>independent release lifecycle\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Do not create separate modules simply because you want to organize source code.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Packages already solve that problem.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">45. Final mental model<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Remember this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GO PROJECT\n   \u2502\n   \u2193\nMODULE\n   \u2502\n   \u2502 defined by\n   \u2193\n go.mod\n   \u2502\n   \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n   \u2193            \u2193             \u2193\nPACKAGE      PACKAGE       PACKAGE\npayment      customer       order\n   \u2502\n   \u2193\n.go files\n   \u2502\n   \u2193\nFunctions \/ Structs \/ Methods \/ Interfaces\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you create another:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go.mod\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">inside:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>payment\/\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">then:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>payment\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">stops being merely a package inside the parent module and becomes the root of another module.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Repository\n\u2502\n\u251c\u2500\u2500 Root Module\n\u2502      \u2514\u2500\u2500 go.mod\n\u2502\n\u2514\u2500\u2500 Payment Module\n       \u2514\u2500\u2500 go.mod\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If several local modules need to be developed together:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go.work\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">can group them:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>               go.work\n                  \u2502\n        \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n        \u2193         \u2193         \u2193\n      Module    Module    Module\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And for release\/production dependencies, think:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go.mod\n   \u2502\n   \u2193\nversioned dependencies\n   \u2502\n   \u251c\u2500\u2500 payment v1.0.0\n   \u251c\u2500\u2500 order v1.0.0\n   \u2514\u2500\u2500 customer v1.0.0\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">46. Final comparison cheat sheet<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Concept<\/th><th>Simple meaning<\/th><th>Main file\/example<\/th><\/tr><\/thead><tbody><tr><td>Repository<\/td><td>Git\/project container<\/td><td><code>.git\/<\/code><\/td><\/tr><tr><td>Module<\/td><td>Versioned collection of Go packages<\/td><td><code>go.mod<\/code><\/td><\/tr><tr><td>Package<\/td><td>Related Go code<\/td><td><code>package payment<\/code><\/td><\/tr><tr><td>Subpackage<\/td><td>Package inside nested directory<\/td><td><code>customer\/validation<\/code><\/td><\/tr><tr><td>Submodule<\/td><td>Separate nested module<\/td><td>Another <code>go.mod<\/code><\/td><\/tr><tr><td>Workspace<\/td><td>Develop multiple modules together<\/td><td><code>go.work<\/code><\/td><\/tr><tr><td>Dependency<\/td><td>External\/separate module required by a module<\/td><td><code>require<\/code><\/td><\/tr><tr><td>Import<\/td><td>Use another package<\/td><td><code>import \"...\"<\/code><\/td><\/tr><tr><td>Exported function<\/td><td>Function usable from another package<\/td><td><code>Pay()<\/code><\/td><\/tr><tr><td>Unexported function<\/td><td>Function private to package<\/td><td><code>pay()<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The one sentence to remember is:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Use packages to organize code, modules to version and distribute code, and <code>go.work<\/code> to conveniently develop multiple local modules together.<\/strong><\/p>\n<\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial gives you one complete mental model for: The most important idea is: And sometimes: These two designs are very different. 1. What is a Go&#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1099","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1099","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/comments?post=1099"}],"version-history":[{"count":1,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1099\/revisions"}],"predecessor-version":[{"id":1100,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1099\/revisions\/1100"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/media?parent=1099"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/categories?post=1099"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/tags?post=1099"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}