ภาพรวม

นี่คือเค้าโครงพื้นฐานสำหรับโปรเจกต์แอปพลิเคชัน Go มัน ไม่ใช่มาตรฐานที่ถูกกำหนดอย่างเป็นทางการโดยทีมพัฒนาของ Go; มันคือโครงสร้างไดเร็กทอรี่ที่ใช้กันอย่างแพร่หลายสำหรับโปรเจกต์ Go ของชุมชน

ถ้าคุณกำลังเรียนรู้ Go หรือกำลังสร้าง proof of concept (PoC) หรือโปรเจกต์ส่วนตัวที่เรียบง่ายโปรเจกต์ นี้ เป็นซับซ้อนเกินไป แทนที่นั้น คุณควรเริ่มต้นด้วยโครงสร้างที่แท้จริงและเรียบง่าย (เพียงแค่ไฟล์ main.go และ go.modพอ) เมื่อโปรเจกต์ของคุณเติบโต ให้ตรวจสอบว่าโค้ดโครงสร้างของคุณดีพอ ไม่งั้นคุณจะได้รับโค้ดที่ยุ่งเหยิงซึ่งมีความขึ้นอยู่กับการตรึงเชิงและสถานะโกลบอล เมื่อมีผู้คนมาเข้ามามีส่วนร่วมในโปรเจกต์ คุณจำเป็นต้องมีวิธีที่มีโครงสร้างมากขึ้น ในกรณีนี้มันสำคัญที่จะนำเสนอวิธีการจัดการแพ็คเกจ/ไลบรารีที่สามารถใช้งานร่วมกัน เมื่อคุณมีโปรเจกต์โอเพ่นซอร์สหรือทราบว่าโปรเจกต์โอนอื่นนำโค้ดมาจากที่เก็บโค้ดโปรเจกต์ของคุณมีการเก็บแพ็คเกจผสม (เรียกว่า internal) และโค้ดจึงสำคัญ โคลนที่เก็บโค้ดไว้เก็บส่วนที่คุณต้องการ และลบสิ่งที่ทั้งหมด! แค่เพราะมันมีอยู่แล้วไม่จำเป็นที่คุณจะต้องใช้มันทั้งหมด ไม่มีรูปแบบทั้งหมดถูกใช้ในทุกโปรเจกต์ แม้แต่รูปแบบ vendor ก็ไม่ได้เป็นที่ยอมรับทั้งหมด

โครงสร้างโปรเจกต์นี้ถูกออกแบบโดยประมาณเพื่อที่จะเป็นทางทั่วไปและไม่แสวงหาที่จะบังคับโครงสร้างแพ็คเกจของ Go ที่กำหนดเองเป็นทางเฉพาะ

การระบุโครงสร้างโปรเจกต์ Go

ด้านล่างนี้คือการระบุโครงสร้างไดเร็กทอรีของโปรเจกต์ Go ที่แนะนำ

.
├── go.mod
├── api
├── assets
├── build
├── cmd
├── configs
├── deployments
├── docs
├── examples
├── githooks
├── go.mod
├── init
├── internal
├── pkg
├── scripts
├── test
├── third_party
├── tools
├── vendor
├── web
└── website

ความหมายของแต่ละไดเร็กทอรีถูกนำเสนอดังต่อไปนี้

/cmd

แอปพลิเคชันหลักของโปรเจกต์ ก็คือจุดเข้าสู่โปรแกรม เป็นไฟล์ Go ในไดเร็กทอรีนี้ที่ปกติจะสร้างไฟล์ที่เป็นไฟล์ทำงานได้. การใช้งานของแต่ละไฟล์ในไดเร็กทอรีต้องตรงกับชื่อของไฟล์สำหรับการทำงานได้ที่คุณต้องการ (เช่น /cmd/myapp).

อย่าใส่โค้ดมากเกินไปในไดเร็กทอรีแอปพลิเคชัน หากคุณคิดว่าโค้ดสามารถนำเข้าและใช้ในโปรเจกต์อื่นได้ให้วางไว้ในไดเร็กทอรี /pkg หากโค้ดไม่สามารถนำไปใช้ใหมดหรือคุณไม่ต้องการให้คนอื่นนำไปใช้ ให้วางโค้ดไว้ในไดเร็กทอรี /internal คุณจะตกใจกับพฤติกรรมของคนอื่น ดังนั้นแสดงความตั้งใจของคุณได้ชัดเจน!

มักจะมีฟังก์ชันหลักที่เล็กน้อยที่นำเข้าและเรียกโค้ดจากไดเร็กทอรี /internal และ /pkg และไม่มีอะไรมาก

/internal

โค้ดแอปพลิเคชันและไลบรารีส่วนตัวนี้คือโค้ดที่คุณไม่ต้องการให้ผู้อื่นนำไปนำเข้าไปในแอปพลิเคชันหรือไลบรารีของพวกเขา โปรดทราบว่าเกริ่นนี้ได้ถูกบังคับโดยตัวคอมไพเลอร์ Go เอง สำหรับข้อมูลเพิ่มเติมโปรดอ้างถึง release notes สำหรับ Go 1.4 ทราบว่ามันไม่จำกัดที่จะต้องเป็นไดเร็กทอรี internal ในระดับบนสุดได้ คุณสามารถมีไดเร็กทอรี internal หลายตัวในทุกระดับของต้นไม้ของโปรเจกต์

คุณสามารถเลือกที่จะเพิ่มโครงสร้างเพิกเก็จเสริมสำหรับแพ็คเกจส่วนที่เป็นแบ่งแยกระหว่างโค้ดแบ่งปันและโค้ดในตัวนี้ นี้ไม่จำเป็น (โดยเฉพาะสำหรับโปรเจกต์ขนาดเล็ก) แสดงให้เห็นว่าวิธีการใช้แพ็คเกจเหมาะสม

/pkg

โค้ดไลบรารีซึ่งสามารถนำไปใช้โดยแอปพลิเคชันภายนอก (เช่น /pkg/mypubliclib) โปรเจกต์โดยอื่นๆ จะนำไลบรารีเหล่านี้นำเข้าและคาดหวังว่ามันจะทำงานอย่างถูกต้องดังนั้นกรุณาคิดอย่างรอบคอบก่อนที่จะวางเนื้อหาที่นี่ :-) เกริ่นนี้ไดเร็กทอรี internal เป็นวิธีที่ดีกว่าในการให้แน่ใจว่าแพ็คเกจส่วนตัวไม่สามารถนำเข้าได้ เพราะมันถูกบังคับจาก Go เอง ไดเร็กทอรี /pkg ก็ยังเป็นทางที่ดีในการแสดงอย่างชัดเจนว่าโค้ดในไดเร็กทอรีนี้สามารถใช้งานได้

หากโปรเจกต์แอปพลิเคชันของคุณมีขนาดเล็กมากและไม่มีการซ้อนซ้อนที่มีประโยชน์มาก ๆ ก็ไม่เป็นไรที่จะไม่ใช้มัน (นอกจากคุณจะต้องการใช้มันแน่ๆ) ขณะที่โปรเจกต์กลายเป็นใหญ่พอและไดเร็กทอรีรากกลายเป็นที่วุ่งวายมากมาย ผลิตการใช้มัน (โดยเฉพาะหากคุณมีส่วนประกอบของแอปพลิเคชันที่ไม่ใช่ Go มากมาย)

/vendor

ความขึ้นต้นของแอปพลิเคชัน (ที่จัดการโดยคนหรือใช้เครื่องมือการจัดการความขึ้นด้วยลักษณะของ Go Modules ที่มาในตัว). คำสั่ง go mod vendor จะสร้างไดเร็กทอรี /vendor ของคุณ. โปรดทราบว่าหากคุณไม่ได้ใช้รุ่นเริ่มต้นที่เปิดใช้งานอยู่ของ Go 1.14 คุณอาจจำเป็นต้องเพิ่มธง -mod=vendor และให้กับคำสั่ง go build.

หากคุณกำลังสร้างไลบรารี โปรดอย่าคอมมิตอะพลิเคชันของคุณที่เป็นตัวลูกของคุณ.

ไดเร็กทอรีแอปพลิเคชันบริการ

/api

สเปกิเฟิเคชัน OpenAPI/Swagger ไฟล์ JSON schema, ไดเร็กทอรีของการกำหนดโปรโตคอล และโปรโตคอล API.

ไดเร็กทอรีแอปพลิเคชันเว็บ

/web

คอมโพเนนต์ที่เฉพาะเจาะจงสำหรับแอปพลิเคชันเว็บ: คุณสมบัติเว็บไซต์สแตติก, เทมเพลตเซิร์ฟเวอร์, และ single-page applications (SPAs).

ไดเร็กทอรีแอปพลิเคชันทั่วไป

/configs

ไฟล์กำหนดค่าเทมเพลต หรือการกำหนดค่าเริ่มต้น.

วางไฟล์เท็มเพลต confd หรือ consul-template ที่นี่.

/init

เริ่มต้นระบบ (systemd, upstart, sysv) และการกำหนดค่าผู้จัดการกระบวนการ/daemon (runit, supervisord).

/scripts

สคริปต์สำหรับการสร้าง, การติดตั้ง, การวิเคราะห์ และปฏิบัติการอื่น ๆ.

/build

การแพกเกจและการอินทิกระบวนการต่อเนื่อง.

วางการกำหนดแพ็คเกจในคลาวด์ (AMI), คอนเทนเนอร์ (Docker), ระบบปฏิบัติการ (deb, rpm, pkg) และสคริปต์ในไดเร็กทอรี /build/package.

วางการกำหนดและสคริปต์ของกระบวนการต่อเนื่อง (travis, circle, drone) ในไดเร็กทอรี /build/ci. โปรดทราบว่าเครื่องมือกระบวนการต่อเนื่องบางอย่าง (เช่น Travis CI) สามารถระบุสถานที่ของไฟล์กำหนดค่าได้อย่างเฉพาะเจาะจง พยายามจัดที่ไฟล์กำหนดค่าในไดเร็กทอรี /build/ci และใช้ลิงค์เชื่อมต่อไปยังสถานที่ที่เครื่องมือกระบวนการต่อเนื่องต้องการ (หากเป็นไปได้).

/deployments

การกำหนดค่าการดีพลอยและเทมเพลตสำหรับ IaaS, PaaS, ระบบ, และ Container Orchestration (docker-compose, kubernetes/helm, terraform). โปรดทราบว่าในบางส่วนคลังข้อมูล (โดยเฉพาะสำหรับแอพพลิเคชันที่ดีพลอยโดยใช้ Kubernetes) ไดเร็กทอรีนี้ถูกเรียกว่า /deploy.

/test

แอพพลิเคชันการทดสอบภายนอกและข้อมูลการทดสอบอื่น ๆ. กรุณาองค์รายไดเร็กทอรี /test อย่างไรก็ได้ตามที่เหมาะกับความต้องการของคุณ. สำหรับโปรเจกต์ขนาดใหญ่การจัดกลุ่มข้อมูลเข้าไดเร็กทอรีย่อยเป็นสิ่งที่เหมาะสม. ตัวอย่างเช่น คุณสามารถสร้างไดเร็กทอรี /test/data หรือ /test/testdata ภายในไดเร็กทอรี /test เพื่อให้ Go ละเว้นเนื้อหา. โปรดทราบว่า Go ยังจะละเว้นไดเร็กทอรีหรือไฟล์ที่ขึ้นต้นด้วย "." หรือ "_" ซึ่งช่วยเสริมความยืดหยุ่นในการตั้งชื่อไดเร็กทอรียข้อมูลทดสอบ.

ไดร์ไร็กทอรีอื่น ๆ

/docs

เอกสารการออกแบบและผู้ใช้ (นอกเหนือจากเอกสาร godoc ที่คุณสร้าง).

/tools

เครื่องมือที่สนับสนุนสำหรับโปรเจกต์นี้. โปรดทราบว่าเครื่องมือเหล่านี้สามารถนำเข้าโค้ดจากไดเร็กทอรี /pkg และ /internal.

/examples

ตัวอย่างสำหรับแอพพลิเคชัน และ/หรือห้องสมุดสาธารณะ.

/third_party

เครื่องมือช่วยแอ็ดจัตเตอร์ภายนอก โค้ดที่ fork และเครื่องมือประโยชน์จากบุคคลที่สาม (เช่น Swagger UI).

/githooks

Git hooks.

/assets

ทรัพยากรเพิ่มเติม (รูปภาพ, โลโก้, ฯลฯ) ที่ให้ไว้ในคลังข้อมูล.

/website

ตำแหน่งสำหรับเก็บข้อมูลเว็บไซต์โปรเจกต์หากคุณไม่ได้ใช้ GitHub Pages.

/src

โปรเจกต์ Go บางตัวอาจมีไดเร็กทอรี src, แต่นี้มักเป็นเพราะนักพัฒนามาจากโลกของ Java ที่เป็นแบบแบรน แต่หากเป็นไปได้โปรดพยายามหลีกเลี่ยงแบบแบรนแบบนี้เหมือนภาษา Java:-) คุณจริงๆ ไม่ต้องการให้โค้ดหรือโปรเจกต์ของคุณดูเหมือน Java:-)

โปรดอย่าสับสนไดเร็กทอรีระดับโปรเจกต์ /src กับไดเร็กทอรี /src ที่ใช้สำหรับช่องทำงาน Go ตามที่อธิบายไว้ใน How to Write Go Code. ตัวแปรสภาพแวดล้อม $GOPATH ชี้ไปยังที่ทำงาน (ปัจจุบัน) ของคุณ (โดยปกติบนระบบที่ไม่ใช่ Windows มันชี้ไปที่ไดเร็กทอรี $HOME/go). ที่ทำงานนี้ประกอบด้วยไดเร็กทอรีระดับบนสุด /pkg, /bin, และ /src. โปรเจกต์จริงของคุณจะเป็นไดเร็กทอรีย่อยภายใต้ไดเร็กทอรี /src ดังนั้นหากโปรเจกต์ของคุณมีไดเร็กทอรี /src เส้นทางโปรเจกต์จะมีลักษณะดังนี้: /some/path/to/workspace/src/your_project/src/your_code.go. โปรดทราบว่าตั้งแต่ Go 1.11 เป็นต้นไปโปรเจกต์ของคุณสามารถอยู่นอก GOPATH แต่นั้นไม่ได้หมายความว่าใช้แบบแบรนแบบนี้คือไอเดียที่ดี