рдЧреЛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдирд╛ рдкрд╣рд▓рд╛ рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреИрд╕реЗ рдмрдирд╛рдПрдВ

рдирдорд╕реНрдХрд╛рд░, рд╣реЗрдмреНрд░! рдореИрдВ рдЖрдкрдХреЗ рд▓рд┐рдП рдЕрдпреВрд▓реБрд╡рд╛ рдпрд╢рд╛рдпрд╛рд╣ рдХреЗ рд▓реЗрдЦ "рдЧреЛ рдХреЗ рд╕рд╛рде рдЕрдкрдирд╛ рдкрд╣рд▓рд╛ рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреИрд╕реЗ рдмрдирд╛рдКрдВ" рдХрд╛ рдЕрдиреБрд╡рд╛рдж рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реВрдВред


рдпрд╣ рдЖрдкрдХреЗ рдкрд╣рд▓реЗ рдЧреЛ рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд▓рд┐рдП рдЧрд╛рдЗрдб рд╣реИред рд╣рдо рдПрдХ рд╕рдорд╛рдЪрд╛рд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдПрдВрдЧреЗ рдЬреЛ рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рд╡рд┐рд╖рдп рдкрд░ рд╕рдорд╛рдЪрд╛рд░ рд▓реЗрдЦ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рдЪрд╛рд░ рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдЕрдВрдд рдореЗрдВ рдЙрддреНрдкрд╛рджрди рд╕рд░реНрд╡рд░ рдкрд░ рддреИрдирд╛рдд рдХрд░рддрд╛ рд╣реИред


рдЖрдк рдЗрд╕ GitHub рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдЗрд╕ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдкреВрд░рд╛ рдХреЛрдб рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред


рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ


рдЗрд╕ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рдПрдХрдорд╛рддреНрд░ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЧреЛ рдЖрдкрдХреЗ рдХрдВрдкреНрдпреВрдЯрд░ рдкрд░ рд╕реНрдерд╛рдкрд┐рдд рд╣реИ рдФрд░ рдЖрдк рдЗрд╕рдХреЗ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдФрд░ рдирд┐рд░реНрдорд╛рдгреЛрдВ рд╕реЗ рдереЛрдбрд╝рд╛ рдкрд░рд┐рдЪрд┐рдд рд╣реИрдВред рдЧреЛ рд╕рдВрд╕реНрдХрд░рдг рдЬрд┐рд╕реЗ рдореИрдВрдиреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдерд╛, рд╡рд╣ рд▓реЗрдЦрди рдХреЗ рд╕рдордп рднреА рдирд╡реАрдирддрдо рд╣реИ: 1.12.9 ред рдЧреЛ рдХреЗ рд╕реНрдерд╛рдкрд┐рдд рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рдЧреЛ go version рдХрдорд╛рдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред


рдпрджрд┐ рдЖрдкрдХреЛ рдпрд╣ рдХрд╛рд░реНрдп рдмрд╣реБрдд рдХрдард┐рди рд▓рдЧрддрд╛ рд╣реИ, рддреЛ рдореЗрд░реЗ рдкрд┐рдЫрд▓реЗ рдкрд░рд┐рдЪрдпрд╛рддреНрдордХ рднрд╛рд╖рд╛ рдкрд╛рда рдкрд░ рдЬрд╛рдПрдВ , рдЬрд┐рд╕рд╕реЗ рдЖрдкрдХреЛ рдЖрд░рдВрдн рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдорд┐рд▓рдиреА рдЪрд╛рд╣рд┐рдПред


рддреЛ рдЪрд▓рд┐рдП рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИ!


рд╣рдо рдирд┐рд░реНрдорд┐рдд рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ GitHub рдФрд░ cd рдкрд░ рдЖрд░рдВрднрд┐рдХ рдлрд╛рдЗрд▓ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЛ рдХреНрд▓реЛрди рдХрд░рддреЗ рд╣реИрдВ ред рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рддреАрди рдореБрдЦреНрдп рдлрд╛рдЗрд▓реЗрдВ рд╣реИрдВ: main.go рдлрд╛рдЗрд▓ рдореЗрдВ main.go рд╣рдо рдЗрд╕ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рд╕рднреА рдЧреЛ рдХреЛрдб рд▓рд┐рдЦреЗрдВрдЧреЗред index.html рдлрд╝рд╛рдЗрд▓ рд╡рд╣ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рд╣реИ рдЬреЛ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЛ рднреЗрдЬрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд▓рд┐рдП assets/styles.css ред


рдПрдХ рдмреЗрд╕рд┐рдХ рд╡реЗрдм рд╕рд░реНрд╡рд░ рдмрдирд╛рдПрдВ


рдЪрд▓реЛ рдПрдХ рдореВрд▓ рд╕рд░реНрд╡рд░ рдмрдирд╛рдиреЗ рд╕реЗ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ рдЬреЛ рд╕рд░реНрд╡рд░ рдХреЛ GET рдЕрдиреБрд░реЛрдз рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╕рдордп рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЛ "рд╣реИрд▓реЛ рд╡рд░реНрд▓реНрдб!" рдкрд╛рда рднреЗрдЬрддрд╛ рд╣реИред рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреА main.go рдлрд╛рдЗрд▓ рдмрджрд▓реЗрдВ:


 package main import ( "net/http" "os" ) func indexHandler(w http.ResponseWriter, r *http.Request) { w.Write([]byte("<h1>Hello World!</h1>")) } func main() { port := os.Getenv("PORT") if port == "" { port = "3000" } mux := http.NewServeMux() mux.HandleFunc("/", indexHandler) http.ListenAndServe(":"+port, mux) } 

package main рдХреА рдкрд╣рд▓реА рдкрдВрдХреНрддрд┐ - рдШреЛрд╖рдгрд╛ рдХрд░рддреА рд╣реИ рдХрд┐ main.go рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдХреЛрдб рдореБрдЦреНрдп рдкреИрдХреЗрдЬ рдХрд╛ рд╣реИред рдЙрд╕рдХреЗ рдмрд╛рдж, рд╣рдордиреЗ net/http рдкреИрдХреЗрдЬ рдХрд╛ рдЖрдпрд╛рдд рдХрд┐рдпрд╛, рдЬреЛ рд╣рдорд╛рд░реЗ рдЖрд╡реЗрджрди рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП HTTP рдХреНрд▓рд╛рдЗрдВрдЯ рдФрд░ рд╕рд░реНрд╡рд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдкреИрдХреЗрдЬ рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдЧреЛ рд╕реНрдерд╛рдкрдирд╛ рдХреЗ рд╕рд╛рде рд╢рд╛рдорд┐рд▓ рд╣реИред


main рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ, http.NewServeMux() рдПрдХ рдирдпрд╛ HTTP рдЕрдиреБрд░реЛрдз рдорд▓реНрдЯреАрдкреНрд▓реЗрдХреНрд╕ рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ mux рд╡реЗрд░рд┐рдПрдмрд▓ рдореЗрдВ рдЕрд╕рд╛рдЗрди рдХрд░рддрд╛ рд╣реИред рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ, рдЕрдиреБрд░реЛрдз рдорд▓реНрдЯреАрдкреНрд▓реЗрдХреНрд╕ рдкрдВрдЬреАрдХреГрдд рдкрдереЛрдВ рдХреА рд╕реВрдЪреА рдореЗрдВ рдЖрдиреЗ рд╡рд╛рд▓реЗ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ URL рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ рдФрд░ рдЬрдм рднреА рдХреЛрдИ рдореИрдЪ рдорд┐рд▓рддрд╛ рд╣реИ, рддреЛ рдкрде рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рд╣реИрдВрдбрд▓рд░ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИред


рдЕрдЧрд▓рд╛, рд╣рдо рд░реВрдЯ рдкрде / рд▓рд┐рдП рдЕрдкрдирд╛ рдкрд╣рд▓рд╛ рд╣реИрдВрдбрд▓рд░ рдлрд╝рдВрдХреНрд╢рди рдкрдВрдЬреАрдХреГрдд рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рд╣реИрдВрдбрд▓рд░ рдлрдВрдХреНрд╢рди рд╣реИрдВрдбрд▓ рдХрд╛ рджреВрд╕рд░рд╛ рддрд░реНрдХ рд╣реИ рдФрд░ рд╣рдореЗрд╢рд╛ рд╕рд┐рдЧреНрдиреЗрдЪрд░ func (w http.ResponseWriter, r * http.Request) ред


рдпрджрд┐ рдЖрдк indexHandler рдлрд╝рдВрдХреНрд╢рди рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдЗрд╕рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рд╣реИ, рдЬреЛ рдЗрд╕реЗ HandleFunc рд▓рд┐рдП рдПрдХ рд╡реИрдз рджреВрд╕рд░рд╛ рддрд░реНрдХ HandleFunc ред w рдкреИрд░рд╛рдореАрдЯрд░ рд╡рд╣ рд╕рдВрд░рдЪрдирд╛ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣рдо HTTP рдЕрдиреБрд░реЛрдз рдХреЗ рдЬрд╡рд╛рдм рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ Write() рд╡рд┐рдзрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдмрд╛рдЗрдЯ рд╕реНрд▓рд╛рдЗрд╕ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рд╕рдВрдпреБрдХреНрдд рдбреЗрдЯрд╛ рдХреЛ HTTP рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рднрд╛рдЧ рдХреЗ рд░реВрдк рдореЗрдВ рд▓рд┐рдЦрддрд╛ рд╣реИред


рджреВрд╕рд░реА рдУрд░, рдкреИрд░рд╛рдореАрдЯрд░ r рдХреНрд▓рд╛рдЗрдВрдЯ рд╕реЗ рдкреНрд░рд╛рдкреНрдд HTTP рдЕрдиреБрд░реЛрдз рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рд╡реЗрдм рдмреНрд░рд╛рдЙрдЬрд╝рд░ рджреНрд╡рд╛рд░рд╛ рд╕рд░реНрд╡рд░ рдкрд░ рднреЗрдЬреЗ рдЧрдП рдбреЗрдЯрд╛ рддрдХ рдХреИрд╕реЗ рдкрд╣реБрдВрдЪрддреЗ рд╣реИрдВред рд╣рдо рдЗрд╕реЗ рдЕрднреА рддрдХ рдпрд╣рд╛рдВ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╣рдо рдмрд╛рдж рдореЗрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЬрд░реВрд░ рдХрд░реЗрдВрдЧреЗред


рдЕрдВрдд рдореЗрдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ http.ListenAndServe() рд╡рд┐рдзрд┐ рд╣реИ, рдЬреЛ рдХрд┐ рдкреЛрд░реНрдЯ 3000 рдХреЛ рд╕рд░реНрд╡рд░ рдкрд░ рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИ рдпрджрд┐ рдкреЛрд░реНрдЯ рдкрд░реНрдпрд╛рд╡рд░рдг рджреНрд╡рд╛рд░рд╛ рд╕реЗрдЯ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдпрджрд┐ рдЖрдкрдХреЗ рдХрдВрдкреНрдпреВрдЯрд░ рдкрд░ 3000 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдПрдХ рдЕрд▓рдЧ рдкреЛрд░реНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВред


рдлрд┐рд░ рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдЦреЗ рдЧрдП рдХреЛрдб рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░реЗрдВ рдФрд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдВ:


 go run main.go 

рдпрджрд┐ рдЖрдк рдЕрдкрдиреЗ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ http: // localhost: 3000 рдкрд░ рдЬрд╛рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ "рд╣реИрд▓реЛ рд╡рд░реНрд▓реНрдб!" рдкрд╛рда рджреЗрдЦрдирд╛ рдЪрд╛рд╣рд┐рдПред


рдмрд╣рд╛рджреБрд░ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╣реИрд▓реЛ рд╡рд░реНрд▓реНрдб рдЯреЗрдХреНрд╕реНрдЯ рджрд┐рдЦрд╛ рд░рд╣рд╛ рд╣реИ


рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдЬрд╛рдПрдВ


рдЖрдЗрдП рджреЗрдЦреЗрдВ рдЧреЛ рдореЗрдВ рдЯреЗрдВрдкрд▓реЗрдЯрд┐рдВрдЧ рдХреА рдореВрд▓ рдмрд╛рддреЗрдВред рдпрджрд┐ рдЖрдк рдЕрдиреНрдп рднрд╛рд╖рд╛рдУрдВ рдХреЗ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реИрдВ, рддреЛ рдЗрд╕реЗ рд╕рдордЭрдирд╛ рдЖрд╕рд╛рди рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред


рдЯреЗрдореНрдкрд▓реЗрдЯ рд╡рд┐рднрд┐рдиреНрди рд╕реНрдерд╛рдиреЛрдВ рдореЗрдВ рд╕рдорд╛рди рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдХреЗ рдмрд┐рдирд╛ рдорд╛рд░реНрдЧ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЖрдкрдХреЗ рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдЖрдЙрдЯрдкреБрдЯ рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдиреЗрд╡рд┐рдЧреЗрд╢рди рдмрд╛рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рдмрд┐рдирд╛ рдХреЛрдб рдХреА рдирдХрд▓ рдХрд┐рдП рд╕рд╛рдЗрдЯ рдХреЗ рд╕рднреА рдкреГрд╖реНрдареЛрдВ рдкрд░ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдореЗрдВ рдЕрдкрдиреЗ рд╡реЗрдм рдкреЗрдЬреЛрдВ рдореЗрдВ рдХреБрдЫ рдмреБрдирд┐рдпрд╛рджреА рддрд░реНрдХ рдЬреЛрдбрд╝рдиреЗ рдХрд╛ рднреА рдЕрд╡рд╕рд░ рдорд┐рд▓рддрд╛ рд╣реИред


рдЬрд╛рдУ рдЕрдкрдиреЗ рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рджреЛ рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ: text/template рдФрд░ html/template ред рджреЛрдиреЛрдВ рдПрдХ рд╣реА рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐ HTML рдЖрдЙрдЯрдкреБрдЯ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП html/template рдкреИрдХреЗрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рдХреЛрдб рдЗрдВрдЬреЗрдХреНрд╢рди рдХреЗ рд╡рд┐рд░реБрджреНрдз рд╕реБрд░рдХреНрд╖рд┐рдд рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдпрд╣рд╛рдВ рдХрд░реЗрдВрдЧреЗред


рдЗрд╕ рдкреИрдХреЗрдЬ рдХреЛ рдЕрдкрдиреА main.go рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЖрдпрд╛рдд рдХрд░реЗрдВ рдФрд░ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:


 package main import ( "html/template" "net/http" "os" ) var tpl = template.Must(template.ParseFiles("index.html")) func indexHandler(w http.ResponseWriter, r *http.Request) { tpl.Execute(w, nil) } func main() { port := os.Getenv("PORT") if port == "" { port = "3000" } mux := http.NewServeMux() mux.HandleFunc("/", indexHandler) http.ListenAndServe(":"+port, mux) } 

tpl рдПрдХ рдкреИрдХреЗрдЬ рд╕реНрддрд░ рдЪрд░ рд╣реИ рдЬреЛ рдкреНрд░рджрд╛рди рдХреА рдЧрдИ рдлрд╝рд╛рдЗрд▓реЛрдВ рд╕реЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИред Template.ParseFiles рдХреЙрд▓ рд╣рдорд╛рд░реЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдбрд╛рдпрд░реЗрдХреНрдЯрд░реА рдХреА рдЬрдбрд╝ рдореЗрдВ index.html рдлрд╝рд╛рдЗрд▓ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреА рд╡реИрдзрддрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддрд╛ рд╣реИред


рд╣рдо template.ParseFiles рдХреЛ template.ParseFiles рд▓рдкреЗрдЯрддреЗ рд╣реИрдВред рдХреЗрд╡рд▓ рдЗрд╕рд▓рд┐рдП рдХрд┐ рдЬрдм рддреНрд░реБрдЯрд┐ рд╣реЛрддреА рд╣реИ рддреЛ рдХреЛрдб рдЖрддрдВрдХ рдХрд╛ рдХрд╛рд░рдг рдмрдирддрд╛ рд╣реИред рддреНрд░реБрдЯрд┐ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп рд╣рдо рдпрд╣рд╛рдВ рдШрдмрд░рд╛рддреЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдХреЛрдб рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд░рдЦрддрд╛ рд╣реИ рдЕрдЧрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдЕрд╡реИрдз рдЯреЗрдореНрдкрд▓реЗрдЯ рд╣реИред рдпрд╣ рдПрдХ рд╕рдорд╕реНрдпрд╛ рд╣реИ рдЬрд┐рд╕реЗ рд╕рд░реНрд╡рд░ рдХреЛ рдкреБрдирдГ рдЖрд░рдВрдн рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдареАрдХ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред


indexHandler рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ indexHandler рд╣рдо рджреЛ рддрд░реНрдХ рдкреНрд░рджрд╛рди рдХрд░рдХреЗ рдкрд╣рд▓реЗ рдмрдирд╛рдП рдЧрдП рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╣реИрдВ: рдЬрд╣рд╛рдВ рд╣рдо рдЖрдЙрдЯрдкреБрдЯ рдФрд░ рдЙрд╕ рдбреЗрдЯрд╛ рдХреЛ рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЬрд┐рд╕реЗ рд╣рдо рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рдкрд╛рд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред


рдЙрдкрд░реЛрдХреНрдд рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо ResponseWriter рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рдЖрдЙрдЯрдкреБрдЯ рд▓рд┐рдЦрддреЗ рд╣реИрдВ рдФрд░, рдЪреВрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЕрдкрдиреЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЛ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдбреЗрдЯрд╛ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП nil рдХреЛ рджреВрд╕рд░реЗ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред


Ctrl-C рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдиреЗ рдЯрд░реНрдорд┐рдирд▓ рдореЗрдВ рдЪрд▓ рд░рд╣реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдмрдВрдж рдХрд░реЗрдВ рдФрд░ рдЗрд╕реЗ go run main.go рд╕рд╛рде рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░реЗрдВ, рдлрд┐рд░ рдЕрдкрдиреЗ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЛ рддрд╛рдЬрд╝рд╛ рдХрд░реЗрдВред рдЖрдкрдХреЛ рдиреАрдЪреЗ рджрд┐рдЦрд╛рдП рдЧрдП рдкреЗрдЬ рдкрд░ "рдиреНрдпреВрдЬрд╝ рдРрдк рдбреЗрдореЛ" рдЯреЗрдХреНрд╕реНрдЯ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рд┐рдП:


рдмрд╣рд╛рджреБрд░ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╕рдорд╛рдЪрд╛рд░ рдРрдк рдбреЗрдореЛ рдкрд╛рда рджрд┐рдЦрд╛ рд░рд╣рд╛ рд╣реИ


рдкреЗрдЬ рдкрд░ рдПрдХ рдиреЗрд╡рд┐рдЧреЗрд╢рди рдмрд╛рд░ рдЬреЛрдбрд╝реЗрдВ


рдиреАрдЪреЗ рджрд┐рдЦрд╛рдП рдЕрдиреБрд╕рд╛рд░ рдЕрдкрдиреА index.html рдлрд╝рд╛рдЗрд▓ рдореЗрдВ <body> рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдмрджрд▓реЗрдВ:


 <main> <header> <a class="logo" href="/">News Demo</a> <form action="/search" method="GET"> <input autofocus class="search-input" value="" placeholder="Enter a news topic" type="search" name="q"> </form> <a href="https://github.com/freshman-tech/news" class="button github-button">View on Github</a> </header> </main> 

рдлрд┐рд░ рд╕рд░реНрд╡рд░ рдХреЛ рд░рд┐рдмреВрдЯ рдХрд░реЗрдВ рдФрд░ рдЕрдкрдиреЗ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЛ рддрд╛рдЬрд╝рд╛ рдХрд░реЗрдВред рдЖрдкрдХреЛ рдЗрд╕рдХреЗ рд╕рдорд╛рди рдХреБрдЫ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рд┐рдП:


рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдЬреЛ рдЕрд╕реНрдерд┐рд░ рдиреЗрд╡рд┐рдЧреЗрд╢рди рдмрд╛рд░ рджрд┐рдЦрд╛ рд░рд╣рд╛ рд╣реИ


рд╕реНрдерд┐рд░ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВ


рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рд╣рдордиреЗ рдЬреЛ рдиреЗрд╡рд┐рдЧреЗрд╢рди рдмрд╛рд░ рдЬреЛрдбрд╝рд╛ рд╣реИ рдЙрд╕рдореЗрдВ рд╢реИрд▓рд┐рдпреЛрдВ рдирд╣реАрдВ рд╣реИ, рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐ рд╣рдордиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЙрдиреНрд╣реЗрдВ рд╣рдорд╛рд░реЗ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреЗ <head> рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛ рд╣реИред


рдРрд╕рд╛ рдЗрд╕рд▓рд┐рдП рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдкрде / рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрди рд╕рднреА рд░рд╛рд╕реНрддреЛрдВ рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ рдЬреЛ рдЕрдиреНрдпрддреНрд░ рд╕рдВрд╕рд╛рдзрд┐рдд рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рдпрджрд┐ рдЖрдк http: // рд▓реЛрдХрд▓рд╣реЛрд╕реНрдЯ: 3000 / рдПрд╕реЗрдЯреНрд╕ / рд╕реНрдЯрд╛рдЗрд▓.рд╕реАрдПрд╕рдПрд╕ рдкрд░ рдЬрд╛рддреЗ рд╣реИрдВ , рддреЛ рдЖрдкрдХреЛ рдЕрднреА рднреА рд╕реАрдПрд╕рдПрд╕ рдлрд╛рдЗрд▓ рдХреЗ рдмрдЬрд╛рдп рдиреНрдпреВрдЬ рдбреЗрдореЛ рд╣реЛрдордкреЗрдЬ рдорд┐рд▓реЗрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рд░реВрдЯ /assets/style.css рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдШреЛрд╖рд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред


рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реА рд╕рднреА рд╕реНрдЯреИрдЯрд┐рдХ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП рд╕реНрдкрд╖реНрдЯ рд╣реИрдВрдбрд▓рд░ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЕрд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╣реИ рдФрд░ рдХреЛрдИ рдкреИрдорд╛рдирд╛ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рд╣рдо рд╕рднреА рд╕реНрдерд┐рд░ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреА рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реИрдВрдбрд▓рд░ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред


рдкрд╣рд▓реА рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдлрд╝рд╛рдЗрд▓ рд╕рд░реНрд╡рд░ рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рдирд╛ рд╣реИ, рдЙрд╕ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рдЧреБрдЬрд░рдирд╛ рдЬрд┐рд╕рдореЗрдВ рд╣рдорд╛рд░реА рд╕рднреА рд╕реНрдерд┐рд░ рдлрд╛рдЗрд▓реЗрдВ рд╕реНрдерд┐рдд рд╣реИрдВ:


 fs := http.FileServer(http.Dir("assets")) 

рдЗрд╕рдХреЗ рдмрд╛рдж, рд╣рдореЗрдВ рдЕрдкрдиреЗ рд░рд╛рдЙрдЯрд░ рдХреЛ рдЗрд╕ рдлрд╛рдЗрд▓ рд╕рд░реНрд╡рд░ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ /assets/ рдкреНрд░реАрдлрд┐рдХреНрд╕ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рд╕рднреА рд░рд╛рд╕реНрддреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрддрд╛рдирд╛ рд╣реЛрдЧрд╛:


 mux.Handle("/assets/", http.StripPrefix("/assets/", fs)) 

рдЕрдм рд╕рднреА рдПрдХ рд╕рд╛рде:


 // main.go //   func main() { port := os.Getenv("PORT") if port == "" { port = "3000" } mux := http.NewServeMux() //     fs := http.FileServer(http.Dir("assets")) mux.Handle("/assets/", http.StripPrefix("/assets/", fs)) mux.HandleFunc("/", indexHandler) http.ListenAndServe(":"+port, mux) } 

рд╕рд░реНрд╡рд░ рдХреЛ рд░реАрдмреВрдЯ рдХрд░реЗрдВ рдФрд░ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЛ рд░рд┐рдлреНрд░реЗрд╢ рдХрд░реЗрдВред рдиреАрдЪреЗ рджреА рдЧрдИ рд╢реИрд▓рд┐рдпреЛрдВ рдХреЛ рдЪрд╛рд▓реВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП:


рдмрд╣рд╛рджреБрд░ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╕реНрдЯрд╛рдЗрд▓ рдиреЗрд╡рд┐рдЧреЗрд╢рди рдкрдЯреНрдЯреА рджрд┐рдЦрд╛ рд░рд╣рд╛ рд╣реИ



рдЖрдЗрдП рдПрдХ рдорд╛рд░реНрдЧ рдмрдирд╛рдПрдВ рдЬреЛ рд╕рдорд╛рдЪрд╛рд░ рд▓реЗрдЦреЛрдВ рдХреЗ рд▓рд┐рдП рдЦреЛрдЬ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИред рд╣рдо рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рдЪрд╛рд░ рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рдпрд╣рд╛рдВ рдореБрдлреНрдд рдПрдкреАрдЖрдИ рдХреБрдВрдЬреА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрдВрдЬреАрдХрд░рдг рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ ред


рдпрд╣ рдорд╛рд░реНрдЧ рджреЛ рдХреНрд╡реЗрд░реА рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реИ: q рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рдХреНрд╡реЗрд░реА рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдкрд░рд┐рдгрд╛рдо рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реНрдХреНрд░реЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП page рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ page рдкреИрд░рд╛рдореАрдЯрд░ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╣реИред рдпрджрд┐ рдпрд╣ URL рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рд╣реИ, рддреЛ рд╣рдо рдмрд╕ рдпрд╣ рдорд╛рди рд▓реЗрддреЗ рд╣реИрдВ рдХрд┐ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреА рдкреГрд╖реНрда рд╕рдВрдЦреНрдпрд╛ "1" рдкрд░ рд╕реЗрдЯ рд╣реИред


indexHandler рддрд╣рдд рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╣реИрдВрдбрд▓рд░ рдХреЛ рдЕрдкрдиреА main.go рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ:


 func searchHandler(w http.ResponseWriter, r *http.Request) { u, err := url.Parse(r.URL.String()) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte("Internal server error")) return } params := u.Query() searchKey := params.Get("q") page := params.Get("page") if page == "" { page = "1" } fmt.Println("Search Query is: ", searchKey) fmt.Println("Results page is: ", page) } 

рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рдЕрдиреБрд░реЛрдз URL рд╕реЗ q рдФрд░ page рдкреИрд░рд╛рдореАрдЯрд░ рдирд┐рдХрд╛рд▓рддрд╛ рд╣реИ рдФрд░ рдЯрд░реНрдорд┐рдирд▓ рдореЗрдВ рджреЛрдиреЛрдВ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред


рдлрд┐рд░ searchHandler рдлрд╝рдВрдХреНрд╢рди рдХреЛ /search рдкрде рд╣реИрдВрдбрд▓рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдкрдВрдЬреАрдХреГрдд рдХрд░реЗрдВ, рдЬреИрд╕рд╛ рдХрд┐ рдиреАрдЪреЗ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ:


 func main() { port := os.Getenv("PORT") if port == "" { port = "3000" } mux := http.NewServeMux() fs := http.FileServer(http.Dir("assets")) mux.Handle("/assets/", http.StripPrefix("/assets/", fs)) // Add the next line mux.HandleFunc("/search", searchHandler) mux.HandleFunc("/", indexHandler) http.ListenAndServe(":"+port, mux) } 

рдКрдкрд░ рд╕реЗ fmt рдФрд░ net/url рд╕рдВрдХреБрд▓ рдЖрдпрд╛рдд рдХрд░рдирд╛ рдпрд╛рдж рд░рдЦреЗрдВ:


 import ( "fmt" "html/template" "net/http" "net/url" "os" ) 

рдЕрдм рд╕рд░реНрд╡рд░ рдХреЛ рдкреБрдирд░рд╛рд░рдВрдн рдХрд░реЗрдВ, рдЦреЛрдЬ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдХреНрд╡реЗрд░реА рджрд░реНрдЬ рдХрд░реЗрдВ рдФрд░ рдЯрд░реНрдорд┐рдирд▓ рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдВред рдЖрдкрдХреЛ рдЯрд░реНрдорд┐рдирд▓ рдореЗрдВ рдЕрдкрдирд╛ рдЕрдиреБрд░реЛрдз рджреЗрдЦрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬреИрд╕рд╛ рдХрд┐ рдиреАрдЪреЗ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ:




рдПрдХ рдбреЗрдЯрд╛ рдореЙрдбрд▓ рдмрдирд╛рдПрдБ


рдЬрдм рд╣рдо News API/everything рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдиреБрд░реЛрдз рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдПрдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреА рдЙрдореНрдореАрдж рдХрд░рддреЗ рд╣реИрдВ:


 { "status": "ok", "totalResults": 4661, "articles": [ { "source": { "id": null, "name": "Gizmodo.com" }, "author": "Jennings Brown", "title": "World's Dumbest Bitcoin Scammer Tries to Scam Bitcoin Educator, Gets Scammed in The Process", "description": "Ben Perrin is a Canadian cryptocurrency enthusiast and educator who hosts a bitcoin show on YouTube. This is immediately apparent after a quick a look at all his social media. Ten seconds of viewing on of his videos will show that he is knowledgeable about diтАж", "url": "https://gizmodo.com/worlds-dumbest-bitcoin-scammer-tries-to-scam-bitcoin-ed-1837032058", "urlToImage": "https://i.kinja-img.com/gawker-media/image/upload/s--uLIW_Oxp--/c_fill,fl_progressive,g_center,h_900,q_80,w_1600/s4us4gembzxlsjrkmnbi.png", "publishedAt": "2019-08-07T16:30:00Z", "content": "Ben Perrin is a Canadian cryptocurrency enthusiast and educator who hosts a bitcoin show on YouTube. This is immediately apparent after a quick a look at all his social media. Ten seconds of viewing on of his videos will show that he is knowledgeable about..." } ] } 

рдЧреЛ рдореЗрдВ рдЗрд╕ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХ рд╕рдВрд░рдЪрдирд╛ рддреИрдпрд╛рд░ рдХрд░рдиреА рд╣реЛрдЧреА рдЬреЛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╢рд░реАрд░ рдХреЛ рдбрд┐рдХреЛрдб рдХрд░рддреЗ рд╕рдордп рдбреЗрдЯрд╛ рдХреЛ рджрд░реНрд╢рд╛рддреА рд╣реИред рдмреЗрд╢рдХ, рдЖрдк рдЗрд╕реЗ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдореИрдВ JSON-to-Go рд╡реЗрдмрд╕рд╛рдЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реВрдВ, рдЬреЛ рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЖрд╕рд╛рди рдмрдирд╛рддрд╛ рд╣реИред рдпрд╣ рдПрдХ рдЧреЛ рд╕рдВрд░рдЪрдирд╛ (рдЯреИрдЧ рдХреЗ рд╕рд╛рде) рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдЗрд╕ JSON рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░реЗрдЧрд╛ред


рдЖрдкрдХреЛ рдмрд╕ JSON рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдХреЙрдкреА рдХрд░рдирд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ JSON рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рдлрд╝реАрд▓реНрдб рдореЗрдВ рдкреЗрд╕реНрдЯ рдХрд░рдирд╛ рд╣реИ, рдлрд┐рд░ рдЖрдЙрдЯрдкреБрдЯ рдХреЙрдкреА рдХрд░реЗрдВ рдФрд░ рдЗрд╕реЗ рдЕрдкрдиреЗ рдХреЛрдб рдореЗрдВ рдкреЗрд╕реНрдЯ рдХрд░реЗрдВред рдпрд╣рд╛рдВ рд╣рдореЗрдВ рдЙрдкрд░реЛрдХреНрдд JSON рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдорд┐рд▓реЗрдЧрд╛:


 type AutoGenerated struct { Status string `json:"status"` TotalResults int `json:"totalResults"` Articles []struct { Source struct { ID interface{} `json:"id"` Name string `json:"name"` } `json:"source"` Author string `json:"author"` Title string `json:"title"` Description string `json:"description"` URL string `json:"url"` URLToImage string `json:"urlToImage"` PublishedAt time.Time `json:"publishedAt"` Content string `json:"content"` } `json:"articles"` } 

JSON рдХреЛ рдЧреЛ рдЯреВрд▓ рджрд┐рдЦрд╛рдиреЗ рд╡рд╛рд▓рд╛ рдмрд╣рд╛рджреБрд░ рдмреНрд░рд╛рдЙрдЬрд╝рд░


рдореИрдВрдиреЗ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдврд╛рдВрдЪреЗ рдореЗрдВ Articles рдЯреБрдХрдбрд╝реЗ рдХреЛ рдЕрд▓рдЧ рдХрд░рдХреЗ рдФрд░ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдирд╛рдо рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдХреЗ AutoGenerated рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдХрдИ рдмрджрд▓рд╛рд╡ рдХрд┐рдП рд╣реИрдВред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд main.go рдЪрд░ рдШреЛрд╖рдгрд╛ main.go рдореЗрдВ main.go рдФрд░ рдЕрдкрдиреЗ рдЖрдпрд╛рдд рдореЗрдВ time рдкреИрдХреЗрдЬ рдЬреЛрдбрд╝реЗрдВ:


 type Source struct { ID interface{} `json:"id"` Name string `json:"name"` } type Article struct { Source Source `json:"source"` Author string `json:"author"` Title string `json:"title"` Description string `json:"description"` URL string `json:"url"` URLToImage string `json:"urlToImage"` PublishedAt time.Time `json:"publishedAt"` Content string `json:"content"` } type Results struct { Status string `json:"status"` TotalResults int `json:"totalResults"` Articles []Article `json:"articles"` } 

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ, рдЧреЛ рдХреЛ рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рд╕рднреА рдирд┐рд░реНрдпрд╛рддрд┐рдд рдлрд╝реАрд▓реНрдб рдПрдХ рдмрдбрд╝реЗ рдЕрдХреНрд╖рд░ рд╕реЗ рд╢реБрд░реВ рд╣реЛрддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрд╣ JSON рдлрд╝реАрд▓реНрдбреНрд╕ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рдерд╛рдЧрдд рд╣реИ, рдЬреЛ CamelCase рдпрд╛ snake_case рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реИ , рдЬреЛ рдХрд┐ рдмрдбрд╝реЗ рдЕрдХреНрд╖рд░ рд╕реЗ рд╢реБрд░реВ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред


рдЗрд╕рд▓рд┐рдП, рд╣рдо рд╕рдВрд░рдЪрдирд╛ рдлрд╝реАрд▓реНрдб рдЯреИрдЧ рдЬреИрд╕реЗ рдХрд┐ json:"id" рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ JSON рдлрд╝реАрд▓реНрдб рдореЗрдВ рд╕рдВрд░рдЪрдирд╛ рдлрд╝реАрд▓реНрдб рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░рддреЗ рд╣реИрдВ, рдЬреИрд╕рд╛ рдХрд┐ рдКрдкрд░ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рддреЛ рдпрд╣ рдЖрдкрдХреЛ рд╕рдВрд░рдЪрдирд╛ рдХреНрд╖реЗрддреНрд░ рдФрд░ рд╕рдВрдмрдВрдзрд┐рдд рдЬреЛрди рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рдирд╛рдореЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рднреА рджреЗрддрд╛ рд╣реИред


рдЕрдВрдд рдореЗрдВ, рдЖрдЗрдП рдкреНрд░рддреНрдпреЗрдХ рдЦреЛрдЬ рдХреНрд╡реЗрд░реА рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рдкреНрд░рдХрд╛рд░ рдХреА рд╕рдВрд░рдЪрдирд╛ рдмрдирд╛рдПрдВред рдореБрдЦреНрдп рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ Results рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдиреАрдЪреЗ рдЗрд╕реЗ рдЬреЛрдбрд╝реЗрдВ:


 type Search struct { SearchKey string NextPage int TotalPages int Results Results } 

рдпрд╣ рд╕рдВрд░рдЪрдирд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рдмрдирд╛рдИ рдЧрдИ рдкреНрд░рддреНрдпреЗрдХ рдЦреЛрдЬ рдХреНрд╡реЗрд░реА рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддреА рд╣реИред SearchKey рд╕реНрд╡рдпрдВ рдХреНрд╡реЗрд░реА рд╣реИ, NextPage рдлрд╝реАрд▓реНрдб NextPage рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реНрдХреНрд░реЙрд▓ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИ, TotalPages - рдХреНрд╡реЗрд░реА рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рдХреБрд▓ рдкреГрд╖реНрда рдФрд░ Results - рдХреНрд╡реЗрд░реА рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рд╡рд░реНрддрдорд╛рди рдкреГрд╖реНрдаред


рд╕рдорд╛рдЪрд╛рд░ рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдЕрдиреБрд░реЛрдз рднреЗрдЬреЗрдВ рдФрд░ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╕реНрддреБрдд рдХрд░реЗрдВ


рдЕрдм рдЬрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╣рдорд╛рд░реЗ рдЖрд╡реЗрджрди рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рдореЙрдбрд▓ рд╣реИ, рддреЛ рдЪрд▓реЗрдВ рдЬрд╛рд░реА рд░рдЦреЗрдВ рдФрд░ рд╕рдорд╛рдЪрд╛рд░ рдПрдкреАрдЖрдИ рд╕реЗ рдЕрдиреБрд░реЛрдз рдХрд░реЗрдВ, рдФрд░ рдлрд┐рд░ рдкреГрд╖реНрда рдкрд░ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╕реНрддреБрдд рдХрд░реЗрдВред


рдЪреВрдВрдХрд┐ рд╕рдорд╛рдЪрд╛рд░ рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП рдПрдкреАрдЖрдИ рдХреБрдВрдЬреА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдХреЛрдб рдореЗрдВ рд╣рд╛рд░реНрдб рдХреЛрдбрд┐рдВрдЧ рдХреЗ рдмрд┐рдирд╛ рдЗрд╕реЗ рдЕрдкрдиреЗ рдЖрд╡реЗрджрди рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рдЦреЛрдЬрдирд╛ рд╣реЛрдЧрд╛ред рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рдЭрдВрдбреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рдЬрд╛рдУ рдПрдХ flag рдкреИрдХреЗрдЬ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рдХреЗ рдЭрдВрдбреЗ рдХреЗ рдмреБрдирд┐рдпрд╛рджреА рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдпрд╣реА рд╡рд╣ рд╣реИ рдЬреЛ рд╣рдо рдпрд╣рд╛рдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВред


рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ apiKey рд╡реИрд░рд┐рдПрдмрд▓ рдХреЗ рддрд╣рдд рдПрдХ рдирдпрд╛ apiKey рд╡реЗрд░рд┐рдПрдмрд▓ рдШреЛрд╖рд┐рдд рдХрд░реЗрдВ:


 var apiKey *string 

рдлрд┐рд░ рдЗрд╕реЗ рдирд┐рдореНрди рдкреНрд░рдХрд╛рд░ рд╕реЗ main рдХрд╛рд░реНрдп рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:


 func main() { apiKey = flag.String("apikey", "", "Newsapi.org access key") flag.Parse() if *apiKey == "" { log.Fatal("apiKey must be set") } //    } 

рдпрд╣рд╛рдВ рд╣рдо рдзреНрд╡рдЬ рдХрд╣рддреЗ рд╣реИрдВред рд╕реНрдЯреНрд░рд┐рдВрдЧ flag.String() рд╡рд┐рдзрд┐, рдЬреЛ рд╣рдореЗрдВ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдзреНрд╡рдЬ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИред рдЗрд╕ рдкрджреНрдзрддрд┐ рдХрд╛ рдкрд╣рд▓рд╛ рддрд░реНрдХ рдзреНрд╡рдЬ рдирд╛рдо рд╣реИ, рджреВрд╕рд░рд╛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рд╣реИ, рдФрд░ рддреАрд╕рд░рд╛ рдЙрдкрдпреЛрдЧ рд╡рд┐рд╡рд░рдг рд╣реИред


рд╕рднреА рдЭрдВрдбреЗ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдкрдХреЛ рдзреНрд╡рдЬ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред flag.Parse() рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрдиреНрд╣реЗрдВ flag.Parse() рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред рдЕрдВрдд рдореЗрдВ, рдЪреВрдВрдХрд┐ apikey рдЗрд╕ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрд╡рд╢реНрдпрдХ рдШрдЯрдХ рд╣реИ, рд╣рдо рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдпрджрд┐ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдлреНрд▓реИрдЧ рдХреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рджреМрд░рд╛рди рд╕реЗрдЯ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рддреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреНрд░реИрд╢ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред


рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдЖрдк рдЕрдкрдиреЗ рдЖрдпрд╛рдд рдореЗрдВ flag рдкреИрдХреЗрдЬ рдХреЛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рдлрд┐рд░ рд╕рд░реНрд╡рд░ рдХреЛ рдкреБрдирд░рд╛рд░рдВрдн рдХрд░реЗрдВ рдФрд░ рдЖрд╡рд╢реНрдпрдХ apikey рдзреНрд╡рдЬ рдХреЛ рдкрд╛рд╕ рдХрд░реЗрдВ, рдЬреИрд╕рд╛ рдХрд┐ рдиреАрдЪреЗ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ:


 go run main.go -apikey=<your newsapi access key> 

рдЕрдЧрд▓рд╛, рдЖрдЗрдП searchHandler рдЬрд╛рд░реА рд░рдЦреЗрдВ рдФрд░ рдЕрдкрдбреЗрдЯ searchHandler рддрд╛рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рдЦреЛрдЬ рдХреНрд╡реЗрд░реА newsapi.org рдкрд░ рднреЗрдЬреА рдЬрд╛рдП рдФрд░ рдкрд░рд┐рдгрд╛рдо рд╣рдорд╛рд░реЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реЛрдВред


рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЙрд▓ рдХреЗ рд╕рд╛рде рджреЛ рдХреЙрд▓ рдХреЛ fmt.Println() рдореЗрдердб рдореЗрдВ рдЦреЛрдЬреЗрдВред


 func searchHandler(w http.ResponseWriter, r *http.Request) { // beginning of the function search := &Search{} search.SearchKey = searchKey next, err := strconv.Atoi(page) if err != nil { http.Error(w, "Unexpected server error", http.StatusInternalServerError) return } search.NextPage = next pageSize := 20 endpoint := fmt.Sprintf("https://newsapi.org/v2/everything?q=%s&pageSize=%d&page=%d&apiKey=%s&sortBy=publishedAt&language=en", url.QueryEscape(search.SearchKey), pageSize, search.NextPage, *apiKey) resp, err := http.Get(endpoint) if err != nil { w.WriteHeader(http.StatusInternalServerError) return } defer resp.Body.Close() if resp.StatusCode != 200 { w.WriteHeader(http.StatusInternalServerError) return } err = json.NewDecoder(resp.Body).Decode(&search.Results) if err != nil { w.WriteHeader(http.StatusInternalServerError) return } search.TotalPages = int(math.Ceil(float64(search.Results.TotalResults / pageSize))) err = tpl.Execute(w, search) if err != nil { w.WriteHeader(http.StatusInternalServerError) } } 

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо Search рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рдПрдХ рдирдпрд╛ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ SearchKey рдЕрдиреБрд░реЛрдз рдореЗрдВ URL рдкреИрд░рд╛рдореАрдЯрд░ q рдХреЗ рдорд╛рди рдореЗрдВ SearchKey рдлрд╝реАрд▓реНрдб рдХрд╛ рдорд╛рди рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВред


рдЙрд╕рдХреЗ рдмрд╛рдж, рд╣рдо page рдЪрд░ рдХреЛ рдкреВрд░реНрдгрд╛рдВрдХ рдореЗрдВ рдмрджрд▓рддреЗ рд╣реИрдВ рдФрд░ рдкрд░рд┐рдгрд╛рдо рдХреЛ search рдЪрд░ рдХреЗ NextPage рдлрд╝реАрд▓реНрдб рдореЗрдВ рдЕрд╕рд╛рдЗрди рдХрд░рддреЗ рд╣реИрдВред рддрдм рд╣рдо pageSize рд╡реИрд░рд┐рдПрдмрд▓ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдЙрд╕рдХрд╛ рдорд╛рди 20 рдкрд░ рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ pageSize рд╡реИрд░рд┐рдПрдмрд▓ рдЙрди рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ, pageSize рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рд╕рдорд╛рдЪрд╛рд░ рдПрдкреАрдЖрдИ рд╡рд╛рдкрд╕ рдЖрдПрдЧрд╛ред рдпрд╣ рдорд╛рди 0 рд╕реЗ 100 рддрдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред


рдлрд┐рд░ рд╣рдо fmt.Sprintf() рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ GET рдЕрдиреБрд░реЛрдз рдХрд░рддреЗ рд╣реИрдВред рдпрджрд┐ рд╕рдорд╛рдЪрд╛рд░ рдПрдкреАрдЖрдИ рдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ 200 рдареАрдХ рдирд╣реАрдВ рд╣реИ, рддреЛ рд╣рдо рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╕рд░реНрд╡рд░ рддреНрд░реБрдЯрд┐ рд▓реМрдЯрд╛рдПрдВрдЧреЗред рдЕрдиреНрдпрдерд╛, рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдирд┐рдХрд╛рдп рдЦреЛрдЬ рдореЗрдВ рдкрд╛рд░реНрд╕ рдХрд┐рдпрд╛ search.Results ред


рддрдм рд╣рдо TotalResults рдлрд╝реАрд▓реНрдб рдХреЛ pageSize рджреНрд╡рд╛рд░рд╛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдХреЗ рдкреГрд╖реНрдареЛрдВ рдХреА рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдХреЛрдИ рдХреНрд╡реЗрд░реА 100 рдкрд░рд┐рдгрд╛рдо рджреЗрддрд╛ рд╣реИ, рдФрд░ рд╣рдо рдПрдХ рдмрд╛рд░ рдореЗрдВ рдХреЗрд╡рд▓ 20 рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдЙрд╕ рдХреНрд╡реЗрд░реА рдХреЗ рд╕рднреА 100 рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЛ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╛рдВрдЪ рдкреГрд╖реНрдареЛрдВ рдХреЛ рд╕реНрдХреНрд░реЙрд▓ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред


рдЙрд╕рдХреЗ рдмрд╛рдж, рд╣рдо рдЕрдкрдиреЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдбреЗрдЯрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рд░реВрдк рдореЗрдВ search рдЪрд░ рдХреЛ рдкрд╛рд╕ рдХрд░рддреЗ search ред рдпрд╣ рд╣рдореЗрдВ рд╣рдорд╛рд░реЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ JSON рдСрдмреНрдЬреЗрдХреНрдЯ рд╕реЗ рдбреЗрдЯрд╛ рдПрдХреНрд╕реЗрд╕ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦреЗрдВрдЧреЗред


index.html рдкрд░ рдЬрд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдиреАрдЪреЗ рджрд┐рдЦрд╛рдП рдЕрдиреБрд╕рд╛рд░ рдЕрдкрдиреЗ рдЖрдпрд╛рдд рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ рди рднреВрд▓реЗрдВ:


 import ( "encoding/json" "flag" "fmt" "html/template" "log" "math" "net/http" "net/url" "os" "strconv" "time" ) 

рдЪрд▓рд┐рдП рдЬрд╛рд░реА рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдкреГрд╖реНрда рдкрд░ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕реЗ <header> рддрд╣рдд рдЬреЛрдбрд╝реЗрдВ:


 <section class="container"> <ul class="search-results"> {{ range .Results.Articles }} <li class="news-article"> <div> <a target="_blank" rel="noreferrer noopener" href="{{.URL}}"> <h3 class="title">{{.Title }}</h3> </a> <p class="description">{{ .Description }}</p> <div class="metadata"> <p class="source">{{ .Source.Name }}</p> <time class="published-date">{{ .PublishedAt }}</time> </div> </div> <img class="article-image" src="{{ .URLToImage }}"> </li> {{ end }} </ul> </section> 

рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рд╕рдВрд░рдЪрдирд╛ рдХреНрд╖реЗрддреНрд░ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдмрд┐рдВрджреБ рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рдСрдкрд░реЗрдЯрд░ рдПрдХ рд╕рдВрд░рдЪрдирд╛ рдСрдмреНрдЬреЗрдХреНрдЯ (рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, search ) рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рдЕрдВрджрд░ рд╣рдо рдХреЗрд╡рд▓ рдлрд╝реАрд▓реНрдб рдирд╛рдо ( {{.Results}} ) рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВред


range рдмреНрд▓реЙрдХ рд╣рдореЗрдВ рдЧреЛ рдореЗрдВ рдПрдХ рд╕реНрд▓рд╛рдЗрд╕ рдкрд░ рдкреБрдирд░рд╛рд╡реГрддрд┐ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдФрд░ рд╕реНрд▓рд╛рдЗрд╕ рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рдХреЗ рд▓рд┐рдП рдХреБрдЫ HTML рдЖрдЙрдЯрдкреБрдЯ рдХрд░рддрд╛ рд╣реИред рдпрд╣рд╛рдБ, рд╣рдо Articles рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдирд┐рд╣рд┐рдд Article рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЗ рдЯреБрдХрдбрд╝реЗ рдкрд░ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдкрд░ HTML рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВред


рд╕рд░реНрд╡рд░ рдХреЛ рд░рд┐рдмреВрдЯ рдХрд░реЗрдВ, рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЛ рддрд╛рдЬрд╝рд╛ рдХрд░реЗрдВ рдФрд░ рдПрдХ рд▓реЛрдХрдкреНрд░рд┐рдп рд╡рд┐рд╖рдп рдкрд░ рд╕рдорд╛рдЪрд╛рд░ рдЦреЛрдЬреЗрдВред рдЖрдкрдХреЛ рдкреНрд░рддрд┐ рдкреГрд╖реНрда 20 рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдорд┐рд▓рдиреА рдЪрд╛рд╣рд┐рдП, рдЬреИрд╕рд╛ рдХрд┐ рдиреАрдЪреЗ рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ рдореЗрдВ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред


рд╕рдорд╛рдЪрд╛рд░ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рджрд┐рдЦрд╛рдиреЗ рд╡рд╛рд▓рд╛ рдмреНрд░рд╛рдЙрдЬрд╝рд░


рд╡рд┐рджреЗрд╢реА рдореЗрдВ рдЦреЛрдЬ рдХреНрд╡реЗрд░реА рд╕рд╣реЗрдЬреЗрдВ


рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЬрдм рдкреГрд╖реНрда рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рд╕рд╛рде рддрд╛рдЬрд╝рд╛ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдЦреЛрдЬ рдХреНрд╡реЗрд░реА рдЗрдирдкреБрдЯ рд╕реЗ рдЧрд╛рдпрдм рд╣реЛ рдЬрд╛рддреА рд╣реИред рдЖрджрд░реНрд╢ рд░реВрдк рд╕реЗ, рдХреНрд╡реЗрд░реА рддрдм рддрдХ рд░рдЦреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдП рдЬрдм рддрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдПрдХ рдирдИ рдЦреЛрдЬ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, Google рдЦреЛрдЬ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред


рд╣рдо рдЕрдкрдиреА index.html рдлрд╝рд╛рдЗрд▓ рдореЗрдВ input рдЯреИрдЧ рдХреЗ value рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рдирд┐рдореНрди рдкреНрд░рдХрд╛рд░ рд╕реЗ рдЖрд╕рд╛рдиреА рд╕реЗ рдареАрдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:


 <input autofocus class="search-input" value="{{ .SearchKey }}" placeholder="Enter a news topic" type="search" name="q"> 

рдЕрдкрдиреЗ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЛ рдкреБрдирд░рд╛рд░рдВрдн рдХрд░реЗрдВ рдФрд░ рдПрдХ рдирдИ рдЦреЛрдЬ рдХрд░реЗрдВред рдЦреЛрдЬ рдХреНрд╡реЗрд░реА рдХреЛ рдиреАрдЪреЗ рджрд┐рдЦрд╛рдП рдЕрдиреБрд╕рд╛рд░ рд╕рд╣реЗрдЬрд╛ рдЬрд╛рдПрдЧрд╛:



рдкреНрд░рд╛рд░реВрдк рдкреНрд░рдХрд╛рд╢рди рдХреА рддрд╛рд░реАрдЦ


рдпрджрд┐ рдЖрдк рдкреНрд░рддреНрдпреЗрдХ рд▓реЗрдЦ рдореЗрдВ рддрд╛рд░реАрдЦ рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдпрд╣ рдЦрд░рд╛рдм рдкрдардиреАрдп рд╣реИред рд╡рд░реНрддрдорд╛рди рдЖрдЙрдЯрдкреБрдЯ рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдХрд┐ рд╕рдорд╛рдЪрд╛рд░ рдПрдкреАрдЖрдИ рд▓реЗрдЦ рдХреА рдкреНрд░рдХрд╛рд╢рди рддрд┐рдерд┐ рдХреИрд╕реЗ рд▓реМрдЯрд╛рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рд╣рдо рдЗрд╕реЗ рдЖрд╕рд╛рдиреА рд╕реЗ Article рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдПрдХ рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝рдХрд░ рдФрд░ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп рджрд┐рдирд╛рдВрдХ рдХреЛ рдкреНрд░рд╛рд░реВрдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред


рдЪрд▓рд┐рдП main.go рдореЗрдВ Article рд╕реНрдЯреНрд░рдХреНрдЪрд░ рдХреЗ рдареАрдХ рдиреАрдЪреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб main.go :


 func (a *Article) FormatPublishedDate() string { year, month, day := a.PublishedAt.Date() return fmt.Sprintf("%v %d, %d", month, day, year) } 

рдпрд╣рд╛рдВ, рдПрдХ рдирдпрд╛ FormatPublishedDate рд╡рд┐рдзрд┐ Article рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдмрдирд╛рдИ рдЧрдИ рд╣реИ, рдФрд░ рдпрд╣ рд╡рд┐рдзрд┐ Article рдореЗрдВ FormatPublishedDate рдлрд╝реАрд▓реНрдб рдХреЛ рдкреНрд░рд╛рд░реВрдкрд┐рдд рдХрд░рддреА рд╣реИ рдФрд░ рдирд┐рдореНрди рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд▓реМрдЯрд╛рддреА рд╣реИ: 10 2009 ред


рдЕрдкрдиреЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рдЗрд╕ рдирдИ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЕрдкрдиреАред .FormatPublishedDate рдлрд╝рд╛рдЗрд▓ рдореЗрдВ .PublishedAt рд╕рд╛рдеред рдлрд┐рд░ рд╕рд░реНрд╡рд░ рдХреЛ рдкреБрдирд░рд╛рд░рдВрдн рдХрд░реЗрдВ рдФрд░ рдкрд┐рдЫрд▓реА рдЦреЛрдЬ рдХреНрд╡реЗрд░реА рдХреЛ рджреЛрд╣рд░рд╛рдПрдВред рдпрд╣ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╕реНрд╡рд░реВрдкрд┐рдд рд╕рдордп рдХреЗ рд╕рд╛рде рдЖрдЙрдЯрдкреБрдЯ рдХрд░реЗрдЧрд╛, рдЬреИрд╕рд╛ рдХрд┐ рдиреАрдЪреЗ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ:


рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╕реНрд╡рд░реВрдкрд┐рдд рддрд╛рд░реАрдЦ рджрд┐рдЦрд╛рдиреЗ рд╡рд╛рд▓рд╛ рдмрд╣рд╛рджреБрд░ рдмреНрд░рд╛рдЙрдЬрд╝рд░


рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреА рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВред


рдЖрдЗрдП рдкреГрд╖реНрда рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреА рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рдХреЗ рд╣рдорд╛рд░реЗ рд╕рдорд╛рдЪрд╛рд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░реЗрдВ, рдФрд░ рдлрд┐рд░ рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рдХреНрд╡реЗрд░реА рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдкрд░рд┐рдгрд╛рдо рдирд╣реАрдВ рдорд┐рд▓рдиреЗ рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдПрдХ рд╕рдВрджреЗрд╢ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВред


рдЖрдкрдХреЛ рдмрд╕ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдХреЛ .container рдмрдЪреНрдЪреЗ рдХреЗ рд░реВрдк рдореЗрдВ рдЬреЛрдбрд╝рдирд╛ рд╣реИ, рдЕрдкрдиреА index.html рдлрд╝рд╛рдЗрд▓ рдореЗрдВ .search-results рддрддреНрд╡ рдХреЗ рдареАрдХ рдКрдкрд░:


 <div class="result-count"> {{ if (gt .Results.TotalResults 0)}} <p>About <strong>{{ .Results.TotalResults }}</strong> results were found.</p> {{ else if (ne .SearchKey "") and (eq .Results.TotalResults 0) }} <p>No results found for your query: <strong>{{ .SearchKey }}</strong>.</p> {{ end }} </div> 

Go , . gt , , TotalResults Results . , .


, SearchKey ( (ne .SearchKey "") ) TotalResults ( (eq .Results.TotalResults 0) ), ┬лNo results found┬╗.


, . ┬лNo results found┬╗.


Browser showing no results found message


. , :


Browser showing results count at the top of the page



20 , , .


Next , . , , Search main.go :


 func (s *Search) IsLastPage() bool { return s.NextPage >= s.TotalPages } 

, NextPage , TotalPages Search . , NextPage , . :


 func searchHandler(w http.ResponseWriter, r *http.Request) { //   search.TotalPages = int(math.Ceil(float64(search.Results.TotalResults / pageSize))) //   if  if ok := !search.IsLastPage(); ok { search.NextPage++ } //    } 

, , . .search-results index.html .


 <div class="pagination"> {{ if (ne .IsLastPage true) }} <a href="/search?q={{ .SearchKey }}&page={{ .NextPage }}" class="button next-page">Next</a> {{ end }} </div> 

, Next .


, href /search q , NextPage page .


Previous . , 1. , CurrentPage() Search , . IsLastPage :


 func (s *Search) CurrentPage() int { if s.NextPage == 1 { return s.NextPage } return s.NextPage - 1 } 

NextPage - 1 , , NextPage 1. , 1 . :


 func (s *Search) PreviousPage() int { return s.CurrentPage() - 1 } 

, Previous , 1. .pagination index.html :


 <div class="pagination"> {{ if (gt .NextPage 2) }} <a href="/search?q={{ .SearchKey }}&page={{ .PreviousPage }}" class="button previous-page">Previous</a> {{ end }} {{ if (ne .IsLastPage true) }} <a href="/search?q={{ .SearchKey }}&page={{ .NextPage }}" class="button next-page">Next</a> {{ end }} </div> 

. , :





, , , , .


index.html :


 <div class="result-count"> {{ if (gt .Results.TotalResults 0)}} <p>About <strong>{{ .Results.TotalResults }}</strong> results were found. You are on page <strong>{{ .CurrentPage }}</strong> of <strong> {{ .TotalPages }}</strong>.</p> {{ else if (ne .SearchKey "") and (eq .Results.TotalResults 0) }} <p>No results found for your query: <strong>{{ .SearchKey }}</strong>.</p> {{ end }} </div> 

, , .


Browser showing current page


Heroku


, , Heroku. , , . . freshman-news .


, Heroku . heroku login , Heroku.


, git- . , git init , , heroku git-. freshman-news .


 heroku git:remote -a freshman-news 

Procfile ( touch Procfile ) :


 web: bin/news-demo -apikey $NEWS_API_KEY 

GitHub Go, , go.mod , . , , .


 module github.com/freshman-tech/news-demo go 1.12.9 

Settings Heroku Reveal Config Vars . NEWS_API_KEY , .


Heroku config variables


, Heroku :


 git add . git commit -m "Initial commit" git push heroku master 

https://__.herokuapp.com , .


рдирд┐рд╖реНрдХрд░реНрд╖


News Go -. , Heroku.


, . - , , .


рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!

Source: https://habr.com/ru/post/hi475390/


All Articles