рдЧреЛрд▓рд╛рдВрдЧ рдордзреАрд▓ рд╡реЗрдм рд╕рд░реНрд╡реНрд╣рд░ рд╡рд┐рдХрд╛рд╕ - рд╕рд╛рдзреНрдпрд╛ рддреЗ рдЬрдЯрд┐рд▓ рдкрд░реНрдпрдВрдд

рдЧреЛрд▓рд╛рдВрдЧ рдордзреАрд▓ рд╡реЗрдм рд╕рд░реНрд╡реНрд╣рд░ рд╡рд┐рдХрд╛рд╕ - рд╕рд╛рдзреНрдпрд╛ рддреЗ рдЬрдЯрд┐рд▓ рдкрд░реНрдпрдВрдд

рдкрд╛рдЪ рд╡рд░реНрд╖рд╛рдВрдкреВрд░реНрд╡реА рдореА рд╕реБрд░реБрд╡рд╛рдд рдХреЗрд▓реА рдЧреЛрдлрд┐рд╢ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рд╛, рдпрд╛рдореБрд│реЗ рдЧреЛрд▓рдВрдЧ рд╢рд┐рдХрдгреНрдпрд╛рдЪреА рд╕рдВрдзреА рдорд┐рд│рд╛рд▓реА. рдорд▓рд╛ рдЬрд╛рдгрд╡рд▓реЗ рдХреА рдЧреЛ рд╣реА рдПрдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рднрд╛рд╖рд╛ рдЖрд╣реЗ, рдЬреА рдЕрдиреЗрдХ рд▓рд╛рдпрдмреНрд░рд░реАрдВрдиреА рдкреВрд░рдХ рдЖрд╣реЗ. рдЧреЛ рдмрд╣реБрдореБрдЦреА рдЖрд╣реЗ: рд╡рд┐рд╢реЗрд╖рддрдГ, рдХреЛрдгрддреНрдпрд╛рд╣реА рд╕рдорд╕реНрдпрд╛рдВрд╢рд┐рд╡рд╛рдп рд╕рд░реНрд╡реНрд╣рд░-рд╕рд╛рдЗрдб рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдпрд╛рдЪрд╛ рд╡рд╛рдкрд░ рдХреЗрд▓рд╛ рдЬрд╛рдК рд╢рдХрддреЛ.

рд╣рд╛ рд▓реЗрдЦ рдЧреЛ рдордзреНрдпреЗ рд╕рд░реНрд╡реНрд╣рд░ рд▓рд┐рд╣рд┐рдгреНрдпрд╛рдмрджреНрджрд▓ рдЖрд╣реЗ. рдЪрд▓рд╛ "рд╣реЕрд▓реЛ рд╡рд░реНрд▓реНрдб!" рд╕рд╛рд░рдЦреНрдпрд╛ рд╕реЛрдкреНрдпрд╛ рдЧреЛрд╖реНрдЯреАрдВрдкрд╛рд╕реВрди рд╕реБрд░реБрд╡рд╛рдд рдХрд░реВ рдЖрдгрд┐ рдЦрд╛рд▓реАрд▓ рдХреНрд╖рдорддрд╛рдВрд╕рд╣ рдЕрдиреБрдкреНрд░рдпреЛрдЧрд╛рд╕рд╣ рд╕рдорд╛рдкреНрдд рдХрд░реВ:

- HTTPS рд╕рд╛рдареА рд▓реЗрдЯреНрд╕ рдПрдирдХреНрд░рд┐рдкреНрдЯ рд╡рд╛рдкрд░рдгреЗ.
тАФ API рд░рд╛рдЙрдЯрд░ рдореНрд╣рдгреВрди рдХрд╛рдо рдХрд░рдд рдЖрд╣реЗ.
- рдорд┐рдбрд▓рд╡реЗрдЕрд░рд╕рд╣ рдХрд╛рд░реНрдп рдХрд░рдгреЗ.
- рд╕реНрдерд┐рд░ рдлрд╛рдЗрд▓реНрд╕рд╡рд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд░рдгреЗ.
- рдпреЛрдЧреНрдп рд╢рдЯрдбрд╛рдЙрди.

рд╕реНрдХрд┐рд▓рдмреЙрдХреНрд╕ рд╢рд┐рдлрд╛рд░рд╕ рдХрд░рддреЛ: рдкреНрд░реЕрдХреНрдЯрд┐рдХрд▓ рдХреЛрд░реНрд╕ "рдкрд╛рдпрдерди рд╡рд┐рдХрд╕рдХ рд╕реБрд░рд╡рд╛рддреАрдкрд╛рд╕реВрди".

рдЖрдореНрд╣реА рдЖрдард╡рдг рдХрд░реВрди рджреЗрддреЛ: рд╕рд░реНрд╡ Habr рд╡рд╛рдЪрдХрд╛рдВрд╕рд╛рдареА - Habr рдкреНрд░реЛрдореЛ рдХреЛрдб рд╡рд╛рдкрд░реВрди рдХреЛрдгрддреНрдпрд╛рд╣реА рд╕реНрдХрд┐рд▓рдмреЙрдХреНрд╕ рдХреЛрд░реНрд╕рдордзреНрдпреЗ рдирд╛рд╡рдиреЛрдВрджрдгреА рдХрд░рддрд╛рдирд╛ 10 рд░реВрдмрд▓ рд╕рд╡рд▓рдд.

рдирдорд╕реНрдХрд╛рд░, рдЬрдЧ!

рддреБрдореНрд╣реА Go рдордзреНрдпреЗ рдЦреВрдк рд▓рд╡рдХрд░ рд╡реЗрдм рд╕рд░реНрд╡реНрд╣рд░ рддрдпрд╛рд░ рдХрд░реВ рд╢рдХрддрд╛. рдпреЗрдереЗ рдПрдХ рд╣рдБрдбрд▓рд░ рд╡рд╛рдкрд░рдгреНрдпрд╛рдЪреЗ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдЖрд╣реЗ рдЬреЗ рд╡рд░ рд╡рдЪрди рджрд┐рд▓реЗрд▓реЗ тАЬрд╣реЕрд▓реЛ, рд╡рд░реНрд▓реНрдб!тАЭ рдкрд░рдд рдХрд░рддреЗ.

package main
 
import (
"fmt"
"net/http"
)
 
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World!")
})
http.ListenAndServe(":80", nil)
}

рдпрд╛рдирдВрддрд░, рдЬрд░ рддреБрдореНрд╣реА рдЕреЕрдкреНрд▓рд┐рдХреЗрд╢рди рдЪрд╛рд▓рд╡рд▓реЗ рдЖрдгрд┐ рдкреЗрдЬ рдЙрдШрдбрд▓реЗ localhost, рдирдВрддрд░ рддреБрдореНрд╣рд╛рд▓рд╛ рд▓рдЧреЗрдЪ "рд╣реЕрд▓реЛ, рд╡рд░реНрд▓реНрдб!" рдордЬрдХреВрд░ рджрд┐рд╕реЗрд▓. (рдЬрд░ рд╕рд░реНрд╡рдХрд╛рд╣реА рдпреЛрдЧреНрдпрд░рд┐рддреНрдпрд╛ рдХрд╛рд░реНрдп рдХрд░рдд рдЕрд╕реЗрд▓ рддрд░ рдирдХреНрдХреАрдЪ).

рдЖрдореНрд╣реА рдирдВрддрд░ рдЕрдиреЗрдХ рд╡реЗрд│рд╛ рд╣рдБрдбрд▓рд░ рд╡рд╛рдкрд░реВ, рдкрд░рдВрддреБ рдкреНрд░рдердо рд╕рд░реНрд╡рдХрд╛рд╣реА рдХрд╕реЗ рдХрд╛рд░реНрдп рдХрд░рддреЗ рддреЗ рд╕рдордЬреВрди рдШреЗрдК.

рдиреЗрдЯ/http

рдЙрджрд╛рд╣рд░рдгрд╛рдиреЗ рдкреЕрдХреЗрдЬ рд╡рд╛рдкрд░рд▓реЗ net/http, рд╕рд░реНрд╡реНрд╣рд░ рдЖрдгрд┐ HTTP рдХреНрд▓рд╛рдпрдВрдЯ рджреЛрдиреНрд╣реА рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рд╣реЗ Go рдордзреАрд▓ рдкреНрд░рд╛рдердорд┐рдХ рд╕рд╛рдзрди рдЖрд╣реЗ. рдХреЛрдб рд╕рдордЬреВрди рдШреЗрдгреНрдпрд╛рд╕рд╛рдареА, рддреАрди рдорд╣рддреНрддреНрд╡рд╛рдЪреНрдпрд╛ рдШрдЯрдХрд╛рдВрдЪрд╛ рдЕрд░реНрде рд╕рдордЬреВрди рдШреЗрдК: http.Handler, http.ServeMux рдЖрдгрд┐ http.Server.

HTTP рд╣рдБрдбрд▓рд░

рдЬреЗрд╡реНрд╣рд╛ рдЖрдореНрд╣рд╛рд▓рд╛ рд╡рд┐рдирдВрддреА рдкреНрд░рд╛рдкреНрдд рд╣реЛрддреЗ, рддреЗрд╡реНрд╣рд╛ рд╣рдБрдбрд▓рд░ рддреНрдпрд╛рдЪреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рддреЛ рдЖрдгрд┐ рдкреНрд░рддрд┐рд╕рд╛рдж рддрдпрд╛рд░ рдХрд░рддреЛ. Go рдордзреАрд▓ рд╣рдБрдбрд▓рд░ рдЦрд╛рд▓реАрд▓рдкреНрд░рдорд╛рдгреЗ рд▓рд╛рдЧреВ рдХреЗрд▓реЗ рдЬрд╛рддрд╛рдд:

type Handler interface {
        ServeHTTP(ResponseWriter, *Request)
}

рдкрд╣рд┐рд▓реЗ рдЙрджрд╛рд╣рд░рдг http.HandleFunc рд╣реЗрд▓реНрдкрд░ рдлрдВрдХреНрд╢рди рд╡рд╛рдкрд░рддреЗ. рд╣реЗ рджреБрд╕рд░реЗ рдлрдВрдХреНрд╢рди рд░реЕрдк рдХрд░рддреЗ, рдЬреЗ рдпрд╛рдордзреВрди http.ResponseWriter рдЖрдгрд┐ http.Request рд▓рд╛ ServeHTTP рдордзреНрдпреЗ рдШреЗрддреЗ.

рджреБрд╕рд▒реНрдпрд╛ рд╢рдмреНрджрд╛рдВрдд, рдЧреЛрд▓рдВрдЧрдордзреАрд▓ рд╣рдБрдбрд▓рд░ рдПрдХрд╛рдЪ рдЗрдВрдЯрд░рдлреЗрд╕рдордзреНрдпреЗ рд╕рд╛рджрд░ рдХреЗрд▓реЗ рдЬрд╛рддрд╛рдд, рдЬреЗ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░рд▓рд╛ рдмрд░реЗрдЪ рдкрд░реНрдпрд╛рдп рджреЗрддрд╛рдд. рдореНрд╣рдгреВрди, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдорд┐рдбрд▓рд╡реЗрдЕрд░ рд╣рдБрдбрд▓рд░ рд╡рд╛рдкрд░реВрди рд▓рд╛рдЧреВ рдХреЗрд▓реЗ рдЬрд╛рддреЗ, рдЬреЗрдереЗ рд╕рд░реНрд╡реНрд╣реЗрдПрдЪрдЯреАрдЯреАрдкреА рдкреНрд░рдердо рдХрд╛рд╣реАрддрд░реА рдХрд░рддреЗ рдЖрдгрд┐ рдирдВрддрд░ рджреБрд╕рд░реНтАНрдпрд╛ рд╣рдБрдбрд▓рд░рдЪреНрдпрд╛ рд╕рд░реНрд╡реНрд╣реЗрдПрдЪрдЯреАрдЯреАрдкреА рдкрджреНрдзрддреАрд▓рд╛ рдХреЙрд▓ рдХрд░рддреЗ.

рд╡рд░ рдирдореВрдж рдХреЗрд▓реНрдпрд╛рдкреНрд░рдорд╛рдгреЗ, рд╣рдБрдбрд▓рд░ рдлрдХреНрдд рд╡рд┐рдирдВрддреНрдпрд╛рдВрдирд╛ рдкреНрд░рддрд┐рд╕рд╛рдж рддрдпрд╛рд░ рдХрд░рддрд╛рдд. рдкрд░рдВрддреБ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╡реЗрд│реА рдХреЛрдгрддреНрдпрд╛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╣рдБрдбрд▓рд░рдЪрд╛ рд╡рд╛рдкрд░ рдХрд░рд╛рд╡рд╛?

рд░рд╛рдЙрдЯрд┐рдВрдЧрдЪреА рд╡рд┐рдирдВрддреА рдХрд░рд╛

рдпреЛрдЧреНрдп рдирд┐рд╡рдб рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА, HTTP рдорд▓реНрдЯреАрдкреНрд▓реЗрдХреНрд╕рд░ рд╡рд╛рдкрд░рд╛. рдЕрдиреЗрдХ рд▓рд╛рдпрдмреНрд░рд░реАрдВрдордзреНрдпреЗ рдпрд╛рд▓рд╛ рдордХреНрд╕рд░ рдХрд┐рдВрд╡рд╛ рд░рд╛рдЙрдЯрд░ рдореНрд╣рдгрддрд╛рдд, рдкрд░рдВрддреБ рддреЗ рд╕рд░реНрд╡ рд╕рдорд╛рди рдЖрд╣реЗрдд. рдорд▓реНрдЯрд┐рдкреНрд▓реЗрдХреНрд╕рд░рдЪреЗ рдХрд╛рд░реНрдп рд╡рд┐рдирдВрддреА рдорд╛рд░реНрдЧрд╛рдЪреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдгреЗ рдЖрдгрд┐ рдпреЛрдЧреНрдп рд╣рдБрдбрд▓рд░ рдирд┐рд╡рдбрдгреЗ рдЖрд╣реЗ.

рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рдЬрдЯрд┐рд▓ рд░рд╛рдЙрдЯрд┐рдВрдЧрд╕рд╛рдареА рд╕рдорд░реНрдерди рдЖрд╡рд╢реНрдпрдХ рдЕрд╕рд▓реНрдпрд╛рд╕, рддреГрддреАрдп-рдкрдХреНрд╖ рд▓рд╛рдпрдмреНрд░рд░реА рд╡рд╛рдкрд░рдгреЗ рдЪрд╛рдВрдЧрд▓реЗ. рдХрд╛рд╣реА рд╕рд░реНрд╡рд╛рдд рдкреНрд░рдЧрдд - рдЧреЛрд░рд┐рд▓рд╛/рдордХреНрд╕ ╨╕ go-chi/chi, рд╣реА рд▓рд╛рдпрдмреНрд░рд░реА рдХреЛрдгрддреНрдпрд╛рд╣реА рд╕рдорд╕реНрдпрд╛рдВрд╢рд┐рд╡рд╛рдп рдЗрдВрдЯрд░рдореАрдбрд┐рдПрдЯ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд░рд╛рдмрд╡рд┐рдгреЗ рд╢рдХреНрдп рдХрд░рддрд╛рдд. рддреНрдпрд╛рдВрдЪреНрдпрд╛ рдорджрддреАрдиреЗ, рдЖрдкрдг рд╡рд╛рдЗрд▓реНрдбрдХрд╛рд░реНрдб рд░рд╛рдЙрдЯрд┐рдВрдЧ рдХреЙрдиреНрдлрд┐рдЧрд░ рдХрд░реВ рд╢рдХрддрд╛ рдЖрдгрд┐ рдЗрддрд░ рдЕрдиреЗрдХ рдХрд╛рд░реНрдпреЗ рдХрд░реВ рд╢рдХрддрд╛. рддреНрдпрд╛рдВрдЪрд╛ рдлрд╛рдпрджрд╛ рдорд╛рдирдХ HTTP рд╣рдБрдбрд▓рд░реНрд╕рд╕рд╣ рд╕реБрд╕рдВрдЧрддрддрд╛ рдЖрд╣реЗ. рдкрд░рд┐рдгрд╛рдореА, рддреБрдореНрд╣реА рд╕реЛрдкрд╛ рдХреЛрдб рд▓рд┐рд╣реВ рд╢рдХрддрд╛ рдЬреЛ рднрд╡рд┐рд╖реНрдпрд╛рдд рд╕реБрдзрд╛рд░рд▓рд╛ рдЬрд╛рдК рд╢рдХрддреЛ.

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

рдХреНрд╡реЗрд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛

рдпрд╛рд╡реНрдпрддрд┐рд░рд┐рдХреНрдд, рдЖрдореНрд╣рд╛рд▓рд╛ рдПрдХ рдШрдЯрдХ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ рдЬреЛ рдпреЗрдгрд╛рд░реНтАНрдпрд╛ рдХрдиреЗрдХреНрд╢рдирд╕рд╛рдареА "рдРрдХрддреЛ" рдЖрдгрд┐ рд╕рд░реНрд╡ рд╡рд┐рдирдВрддреНрдпрд╛ рдпреЛрдЧреНрдп рд╣рдБрдбрд▓рд░рдХрдбреЗ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░реЗрд▓. http.Server рд╣реЗ рдХрд╛рд░реНрдп рд╕рд╣рдЬрдкрдгреЗ рд╣рд╛рддрд╛рд│реВ рд╢рдХрддреЗ.

рдЦрд╛рд▓реАрд▓ рджрд░реНрд╢рд╡рд┐рддреЗ рдХреА рд╕рд░реНрд╡реНрд╣рд░ рдХрдиреЗрдХреНрд╢рди рдкреНрд░рдХреНрд░рд┐рдпреЗрд╢реА рд╕рдВрдмрдВрдзрд┐рдд рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рд╕рд░реНрд╡ рдХрд╛рд░реНрдпрд╛рдВрд╕рд╛рдареА рдЬрдмрд╛рдмрджрд╛рд░ рдЖрд╣реЗ. рд╣реЗ, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, TLS рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рд╡рд╛рдкрд░реВрди рдХрд╛рд░реНрдп рдХрд░рддреЗ. http.ListenAndServer рдХреЙрд▓рдЪреА рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреА рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА, рдПрдХ рдорд╛рдирдХ HTTP рд╕рд░реНрд╡реНрд╣рд░ рд╡рд╛рдкрд░рд▓рд╛ рдЬрд╛рддреЛ.

рдЖрддрд╛ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдЙрджрд╛рд╣рд░рдгреЗ рдкрд╛рд╣реВ.

рд▓реЗрдЯреНрд╕ рдПрдирдХреНрд░рд┐рдкреНрдЯ рдЬреЛрдбрдд рдЖрд╣реЗ

рдбреАрдлреЙрд▓реНрдЯрдиреБрд╕рд╛рд░, рдЖрдордЪрд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧ HTTP рдкреНрд░реЛрдЯреЛрдХреЙрд▓рд╡рд░ рдЪрд╛рд▓рддреЛ, рдкрд░рдВрддреБ HTTPS рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рд╡рд╛рдкрд░рдгреНрдпрд╛рдЪреА рд╢рд┐рдлрд╛рд░рд╕ рдХреЗрд▓реА рдЬрд╛рддреЗ. рд╣реЗ Go рдордзреНрдпреЗ рд╕рдорд╕реНрдпрд╛рдВрд╢рд┐рд╡рд╛рдп рдХреЗрд▓реЗ рдЬрд╛рдК рд╢рдХрддреЗ. рдЬрд░ рддреБрдореНрд╣рд╛рд▓рд╛ рдкреНрд░рдорд╛рдгрдкрддреНрд░ рдЖрдгрд┐ рдЦрд╛рдЬрдЧреА рдХреА рдкреНрд░рд╛рдкреНрдд рдЭрд╛рд▓реА рдЕрд╕реЗрд▓, рддрд░ рдпреЛрдЧреНрдп рдкреНрд░рдорд╛рдгрдкрддреНрд░ рдЖрдгрд┐ рдХреА рдлрд╛рдЗрд▓реНрд╕рд╕рд╣ ListenAndServeTLS рдЪреА рдиреЛрдВрджрдгреА рдХрд░рдгреЗ рдкреБрд░реЗрд╕реЗ рдЖрд╣реЗ.

http.ListenAndServeTLS(":443", "cert.pem", "key.pem", nil)

рдЖрдкрдг рдиреЗрд╣рдореА рдЪрд╛рдВрдЧрд▓реЗ рдХрд░реВ рд╢рдХрддрд╛.

рдЪрд▓рд╛ рдПрдирдХреНрд░рд┐рдкреНрдЯ рдХрд░рд╛ рд╕реНрд╡рдпрдВрдЪрд▓рд┐рдд рдиреВрддрдиреАрдХрд░рдгрд╛рд╕рд╣ рд╡рд┐рдирд╛рдореВрд▓реНрдп рдкреНрд░рдорд╛рдгрдкрддреНрд░реЗ рдкреНрд░рджрд╛рди рдХрд░рддреЗ. рд╕реЗрд╡рд╛ рд╡рд╛рдкрд░рдгреНрдпрд╛рд╕рд╛рдареА, рддреБрдореНрд╣рд╛рд▓рд╛ рдкреЕрдХреЗрдЬрдЪреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЖрд╣реЗ autocert.

рд╣реЗ рдХреЙрдиреНрдлрд┐рдЧрд░ рдХрд░рдгреНрдпрд╛рдЪрд╛ рд╕рд░реНрд╡рд╛рдд рд╕реЛрдкрд╛ рдорд╛рд░реНрдЧ рдореНрд╣рдгрдЬреЗ http.Serve рд╕рд╣ autocert.NewListener рдкрджреНрдзрдд рд╡рд╛рдкрд░рдгреЗ. HTTP рд╕рд░реНрд╡реНрд╣рд░ рд╡рд┐рдирдВрддреНрдпрд╛рдВрдЪреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд░рдд рдЕрд╕рддрд╛рдирд╛ рд╣реА рдкрджреНрдзрдд рддреБрдореНрд╣рд╛рд▓рд╛ TLS рдкреНрд░рдорд╛рдгрдкрддреНрд░реЗ рдорд┐рд│рд╡рдгреНрдпрд╛рдЪреА рдЖрдгрд┐ рдЕрдкрдбреЗрдЯ рдХрд░рдгреНрдпрд╛рдЪреА рдкрд░рд╡рд╛рдирдЧреА рджреЗрддреЗ:

http.Serve(autocert.NewListener("example.com"), nil)

рдЬрд░ рдЖрдкрдг рдмреНрд░рд╛рдЙрдЭрд░рдордзреНрдпреЗ рдЙрдШрдбрд▓реЗ рддрд░ Example.com, рдЖрдореНрд╣рд╛рд▓рд╛ HTTPS рдкреНрд░рддрд┐рд╕рд╛рдж "рд╣реЕрд▓реЛ, рд╡рд░реНрд▓реНрдб!" рдкреНрд░рд╛рдкреНрдд рд╣реЛрдИрд▓.

рддреБрдореНрд╣рд╛рд▓рд╛ рдЕрдзрд┐рдХ рддрдкрд╢реАрд▓рд╡рд╛рд░ рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рд╣рд╡реЗ рдЕрд╕рд▓реНрдпрд╛рд╕, рддреБрдореНрд╣реА autocert.Manager рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ рд╡рд╛рдкрд░рд╛рд╡реЗ. рдордЧ рдЖрдореНрд╣реА рдЖрдордЪреЗ рд╕реНрд╡рддрдГрдЪреЗ http.Server рдЙрджрд╛рд╣рд░рдг рддрдпрд╛рд░ рдХрд░рддреЛ (рдЖрддрд╛рдкрд░реНрдпрдВрдд рдЖрдореНрд╣реА рддреЗ рдбреАрдлреЙрд▓реНрдЯрдиреБрд╕рд╛рд░ рд╡рд╛рдкрд░рддреЛ) рдЖрдгрд┐ рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ TLSConfig рд╕рд░реНрд╡реНрд╣рд░рдордзреНрдпреЗ рдЬреЛрдбрддреЛ:

m := &autocert.Manager{
Cache:      autocert.DirCache("golang-autocert"),
Prompt:     autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist("example.org", "www.example.org"),
}
server := &http.Server{
    Addr:      ":443",
    TLSConfig: m.TLSConfig(),
}
server.ListenAndServeTLS("", "")

рд╕реНрд╡рдпрдВрдЪрд▓рд┐рдд рдкреНрд░рдорд╛рдгрдкрддреНрд░ рдиреВрддрдиреАрдХрд░рдгрд╛рд╕рд╣ рд╕рдВрдкреВрд░реНрдг HTTPS рд╕рдорд░реНрдерди рд▓рд╛рдЧреВ рдХрд░рдгреНрдпрд╛рдЪрд╛ рд╣рд╛ рдПрдХ рд╕реЛрдкрд╛ рдорд╛рд░реНрдЧ рдЖрд╣реЗ.

рд╕рд╛рдиреБрдХреВрд▓ рдорд╛рд░реНрдЧ рдЬреЛрдбрдд рдЖрд╣реЗ

рдорд╛рдирдХ рд▓рд╛рдпрдмреНрд░рд░реАрдордзреНрдпреЗ рд╕рдорд╛рд╡рд┐рд╖реНрдЯ рдХреЗрд▓реЗрд▓рд╛ рдбреАрдлреЙрд▓реНрдЯ рд░рд╛рдЙрдЯрд░ рдЪрд╛рдВрдЧрд▓рд╛ рдЖрд╣реЗ, рдкрд░рдВрддреБ рддреЛ рдЕрдЧрджреА рдореВрд▓рднреВрдд рдЖрд╣реЗ. рдмрд░реНтАНрдпрд╛рдЪ рдНрдкреНрд▓рд┐рдХреЗрд╢рдиреНрд╕рдирд╛ рдиреЗрд╕реНрдЯреЗрдб рдЖрдгрд┐ рд╡рд╛рдЗрд▓реНрдбрдХрд╛рд░реНрдб рдорд╛рд░реНрдЧрд╛рдВрд╕рд╣ рдХрд┐рдВрд╡рд╛ рдкрде рдкреЕрдЯрд░реНрди рдЖрдгрд┐ рдкреЕрд░рд╛рдореАрдЯрд░реНрд╕ рд╕реЗрдЯ рдХрд░рдгреНрдпрд╛рдЪреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдпрд╛рд╕рд╣ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд░рд╛рдЙрдЯрд┐рдВрдЧрдЪреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЕрд╕рддреЗ.

рдпрд╛ рдкреНрд░рдХрд░рдгрд╛рдд рдкреЕрдХреЗрдЬреЗрд╕ рд╡рд╛рдкрд░рдгреЗ рдлрд╛рдпрджреЗрд╢реАрд░ рдЖрд╣реЗ рдЧреЛрд░рд┐рд▓рд╛/рдордХреНрд╕ ╨╕ go-chi/chi. рдЖрдореНрд╣реА рдирдВрддрд░рдЪреЗ рдХрд╕реЗ рдХрд╛рд░реНрдп рдХрд░рд╛рд╡реЗ рддреЗ рд╢рд┐рдХреВ - рдПрдХ рдЙрджрд╛рд╣рд░рдг рдЦрд╛рд▓реА рджрд░реНрд╢рд╡рд┐рд▓реЗ рдЖрд╣реЗ.

рдЖрдордЪреНрдпрд╛ API рд╕рд╛рдареА рдорд╛рд░реНрдЧ рдЕрд╕рд▓реЗрд▓реА api/v1/api.go рдлрд╛рдЗрд▓ рджрд┐рд▓реА рдЖрд╣реЗ:

/ HelloResponse is the JSON representation for a customized message
type HelloResponse struct {
Message string `json:"message"`
}
 
// HelloName returns a personalized JSON message
func HelloName(w http.ResponseWriter, r *http.Request) {
name := chi.URLParam(r, "name")
response := HelloResponse{
Message: fmt.Sprintf("Hello %s!", name),
}
jsonResponse(w, response, http.StatusOK)
}
 
// NewRouter returns an HTTP handler that implements the routes for the API
func NewRouter() http.Handler {
r := chi.NewRouter()
r.Get("/{name}", HelloName)
return r
}

рдЖрдореНрд╣реА рдореБрдЦреНрдп рдлрд╛рдИрд▓рдордзреАрд▓ рдорд╛рд░реНрдЧрд╛рдВрд╕рд╛рдареА api/vq рдЙрдкрд╕рд░реНрдЧ рд╕реЗрдЯ рдХрд░рддреЛ.

рдЖрдореНрд╣реА рдирдВрддрд░ рдЖрдордЪреНрдпрд╛ рдореБрдЦреНрдп рдЕрдиреБрдкреНрд░рдпреЛрдЧрд╛рдд рдкрд░рдд api/v1/ рдЙрдкрд╕рд░реНрдЧ рдЕрдВрддрд░реНрдЧрдд рдЖрдордЪреНрдпрд╛ рдореБрдЦреНрдп рд░рд╛рдЙрдЯрд░рд╡рд░ рд╣реЗ рдорд╛рдЙрдВрдЯ рдХрд░реВ рд╢рдХрддреЛ:

// NewRouter returns a new HTTP handler that implements the main server routes
func NewRouter() http.Handler {
router := chi.NewRouter()
    router.Mount("/api/v1/", v1.NewRouter())
    return router
}
http.Serve(autocert.NewListener("example.com"), NewRouter())

Go рдЪреНрдпрд╛ рдЬрдЯрд┐рд▓ рдорд╛рд░реНрдЧрд╛рдВрд╕рд╣ рдХрд╛рд░реНрдп рдХрд░рдгреЗ рд╕реБрд▓рднрддреЗрдореБрд│реЗ рдореЛрдареНрдпрд╛, рдЬрдЯрд┐рд▓ рдЕрдиреБрдкреНрд░рдпреЛрдЧрд╛рдВрдЪреА рд╕рдВрд░рдЪрдирд╛ рдЖрдгрд┐ рджреЗрдЦрднрд╛рд▓ рд╕реБрд▓рдн рдХрд░рдгреЗ рд╢рдХреНрдп рд╣реЛрддреЗ.

рдорд┐рдбрд▓рд╡реЗрдЕрд░рд╕рд╣ рдХрд╛рд░реНрдп рдХрд░рдгреЗ

рд╕реНрдЯреЗрдЬрд┐рдВрдЧрдордзреНрдпреЗ рдПрдХрд╛ HTTP рд╣рдБрдбрд▓рд░рд▓рд╛ рджреБрд╕-рдпрд╛рд╕рд╣ рдЧреБрдВрдбрд╛рд│рдгреЗ рд╕рдорд╛рд╡рд┐рд╖реНрдЯ рдЖрд╣реЗ, рдЬреНрдпрд╛рдореБрд│реЗ рдкреНрд░рдорд╛рдгреАрдХрд░рдг, рдХреЙрдореНрдкреНрд░реЗрд╢рди, рд▓реЙрдЧрд┐рдВрдЧ рдЖрдгрд┐ рдЗрддрд░ рдЕрдиреЗрдХ рдХрд╛рд░реНрдпреЗ рджреНрд░реБрддрдкрдгреЗ рдХрд░рдгреЗ рд╢рдХреНрдп рд╣реЛрддреЗ.

рдЙрджрд╛рд╣рд░рдг рдореНрд╣рдгреВрди, http.Handler рдЗрдВрдЯрд░рдлреЗрд╕ рдкрд╛рд╣реВ; рд╕реЗрд╡рд╛ рд╡рд╛рдкрд░рдХрд░реНрддреНрдпрд╛рдВрдирд╛ рдкреНрд░рдорд╛рдгреАрдХреГрдд рдХрд░рдгрд╛рд░рд╛ рд╣рдБрдбрд▓рд░ рд▓рд┐рд╣рд┐рдгреНрдпрд╛рд╕рд╛рдареА рдЖрдореНрд╣реА рддреНрдпрд╛рдЪрд╛ рд╡рд╛рдкрд░ рдХрд░реВ.

func RequireAuthentication(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        if !isAuthenticated(r) {
            http.Redirect(w, r, "/login", http.StatusTemporaryRedirect)
            return
        }
        // Assuming authentication passed, run the original handler
        next.ServeHTTP(w, r)
    })
}

рдЪреА рд╕рд╛рд░рдЦреЗ рддреГрддреАрдп рдкрдХреНрд╖ рд░рд╛рдЙрдЯрд░ рдЖрд╣реЗрдд, рдЬреЗ рддреБрдореНрд╣рд╛рд▓рд╛ рдорд┐рдбрд▓рд╡реЗрдЕрд░ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╡рд╛рдврд╡рдгреНрдпрд╛рдЪреА рдкрд░рд╡рд╛рдирдЧреА рджреЗрддрд╛рдд.

рд╕реНрдерд┐рд░ рдлрд╛рдЗрд▓реНрд╕рд╕рд╣ рдХрд╛рд░реНрдп рдХрд░рдгреЗ

рдЧреЛ рдорд╛рдирдХ рд▓рд╛рдпрдмреНрд░рд░реАрдордзреНрдпреЗ рдкреНрд░рддрд┐рдорд╛, JavaScript рдЖрдгрд┐ CSS рдлрд╛рдпрд▓реАрдВрд╕рд╣ рд╕реНрдерд┐рд░ рд╕рд╛рдордЧреНрд░реАрд╕рд╣ рдХрд╛рд░реНрдп рдХрд░рдгреНрдпрд╛рдЪреА рдХреНрд╖рдорддрд╛ рд╕рдорд╛рд╡рд┐рд╖реНрдЯ рдЖрд╣реЗ. рддреЗ http.FileServer рдлрдВрдХреНрд╢рдирджреНрд╡рд╛рд░реЗ рдНрдХреНрд╕реЗрд╕ рдХреЗрд▓реЗ рдЬрд╛рдК рд╢рдХрддрд╛рдд. рд╣реЗ рдПрдХ рд╣рдБрдбрд▓рд░ рдкрд░рдд рдХрд░рддреЗ рдЬреЗ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдирд┐рд░реНрджреЗрд╢рд┐рдХреЗрддреВрди рдлрд╛рдЗрд▓реНрд╕ рд╕рд░реНрд╡реНрд╣ рдХрд░рддреЗ.

func NewRouter() http.Handler {
    router := chi.NewRouter()
    r.Get("/{name}", HelloName)
 
// ╨Э╨░╤Б╤В╤А╨╛╨╣╨║╨░ ╤А╨░╨╖╨┤╨░╤З╨╕ ╤Б╤В╨░╤В╨╕╤З╨╡╤Б╨║╨╕╤Е ╤Д╨░╨╣╨╗╨╛╨▓
staticPath, _ := filepath.Abs("../../static/")
fs := http.FileServer(http.Dir(staticPath))
    router.Handle("/*", fs)
    
    return r

рд╣реЗ рдирд┐рд╢реНрдЪрд┐рддрдкрдгреЗ рд▓рдХреНрд╖рд╛рдд рдареЗрд╡рдгреНрдпрд╛рд╕рд╛рд░рдЦреЗ рдЖрд╣реЗ рдХреА http.Dir рдирд┐рд░реНрджреЗрд╢рд┐рдХреЗрддреАрд▓ рд╕рд╛рдордЧреНрд░реА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреЗ рдЬрд░ рддреНрдпрд╛рдд рдореБрдЦреНрдп index.html рдлрд╛рдЗрд▓ рдирд╕реЗрд▓. рдпрд╛ рдкреНрд░рдХрд░рдгрд╛рдд, рдирд┐рд░реНрджреЗрд╢рд┐рдХреЗрд╢реА рддрдбрдЬреЛрдб рд╣реЛрдгреНрдпрд╛рдкрд╛рд╕реВрди рд░реЛрдЦрдгреНрдпрд╛рд╕рд╛рдареА, рдЖрдкрдг рдкреЕрдХреЗрдЬ рд╡рд╛рдкрд░рд╛рд╡реЗ unindexed.

рдпреЛрдЧреНрдп рд╢рдЯрдбрд╛рдЙрди

рдЧреЛ рдордзреНрдпреЗ HTTP рд╕рд░реНрд╡реНрд╣рд░рдЪреЗ рдЧреНрд░реЗрд╕рдлреБрд▓ рд╢рдЯрдбрд╛рдЙрди рдирд╛рд╡рд╛рдЪреЗ рд╡реИрд╢рд┐рд╖реНрдЯреНрдп рджреЗрдЦреАрд▓ рдЖрд╣реЗ. рд╣реЗ рд╢рдЯрдбрд╛рдЙрди() рдкрджреНрдзрдд рд╡рд╛рдкрд░реВрди рдХреЗрд▓реЗ рдЬрд╛рдК рд╢рдХрддреЗ. рд╕рд░реНрд╡реНрд╣рд░ рдЧреЛрд░реЛрдЯреАрдирдордзреНрдпреЗ рд╕реБрд░реВ рдХреЗрд▓рд╛ рдЬрд╛рддреЛ рдЖрдгрд┐ рдирдВрддрд░ рдЪреЕрдиреЗрд▓рд▓рд╛ рд╡реНрдпрддреНрдпрдп рд╕рд┐рдЧреНрдирд▓ рдкреНрд░рд╛рдкреНрдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдРрдХрд▓реЗ рдЬрд╛рддреЗ. рд╕рд┐рдЧреНрдирд▓ рдорд┐рд│рддрд╛рдЪ, рд╕рд░реНрд╡реНрд╣рд░ рдмрдВрдж рд╣реЛрддреЛ, рдкрд░рдВрддреБ рд▓рдЧреЗрдЪ рдирд╛рд╣реА, рдкрд░рдВрддреБ рдХрд╛рд╣реА рд╕реЗрдХрдВрджрд╛рдВрдирдВрддрд░.

handler := server.NewRouter()
srv := &http.Server{
    Handler: handler,
}
 
go func() {
srv.Serve(autocert.NewListener(domains...))
}()
 
// Wait for an interrupt
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
<-c
 
// Attempt a graceful shutdown
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
srv.Shutdown(ctx)

рдирд┐рд╖реНрдХрд░реНрд╖ рдореНрд╣рдгреВрди

рдЧреЛ рд╣реА рдЬрд╡рд│рдЬрд╡рд│ рд╕рд╛рд░реНрд╡рддреНрд░рд┐рдХ рдорд╛рдирдХ рд▓рд╛рдпрдмреНрд░рд░реА рдЕрд╕рд▓реЗрд▓реА рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рднрд╛рд╖рд╛ рдЖрд╣реЗ. рддреНрдпрд╛рдЪреА рдбреАрдлреЙрд▓реНрдЯ рдХреНрд╖рдорддрд╛ рдЦреВрдк рд╡рд┐рд╕реНрддреГрдд рдЖрд╣реЗ рдЖрдгрд┐ рддреА рдЗрдВрдЯрд░рдлреЗрд╕ рд╡рд╛рдкрд░реВрди рд╡рд░реНрдзрд┐рдд рдХреЗрд▓реА рдЬрд╛рдК рд╢рдХрддреЗ - рд╣реЗ рддреБрдореНрд╣рд╛рд▓рд╛ рдЦрд░реЛрдЦрд░ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп HTTP рд╕рд░реНрд╡реНрд╣рд░ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдгреНрдпрд╛рд╕ рдЕрдиреБрдорддреА рджреЗрддреЗ.

рд╕реНрдХрд┐рд▓рдмреЙрдХреНрд╕ рд╢рд┐рдлрд╛рд░рд╕ рдХрд░рддреЛ:

рд╕реНрддреНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╛