GoLang Tutorial – Web App Deel 1

In dit bericht zullen we leren hoe we een eenvoudige applicatie kunnen maken. Deze zal uit verschillende delen bestaan en is gebaseerd op https://golang.org/doc/articles/wiki/.
Dit zal een goede aanvulling zijn op onze snelle basis tutorials die we tot nu toe hebben geoefend.
We maken een nieuwe map genaamd gowiki ergens onder $GOTPAH:
$ echo $GOPATH~/go$ mkdir -p $GOPATH/src/github.com/einsteinish/go_tutorial/gowiki
Maak een bestand wiki.go zoals dit:
We importeren de pakketten fmt en ioutil uit de Go-standaardbibliotheek. Later, als we extra functionaliteit implementeren, zullen we meer pakketten toevoegen aan deze importdeclaratie.
Een wiki bestaat uit een reeks pagina’s, die elk een titel en een body (de pagina-inhoud) hebben. Hier definiëren we Pagina als een struct met twee velden die de titel en de body voorstellen.
type Page struct { Title string Body byte}
Het type byte betekent een byte slice.
Het Body-element is een byte in plaats van een string, omdat dat het type is dat wordt verwacht door de io-bibliotheken die we zullen gebruiken.
De Pagina struct beschrijft hoe de paginagegevens in het geheugen zullen worden opgeslagen. Maar hoe zit het met persistente opslag? Dat kunnen we aanpakken door een save() methode te maken voor Page:
func (p *Page) save() error { filename := p.Title + ".txt" return ioutil.WriteFile(filename, p.Body, 0600)}
De save() methode vertelt “Dit is een methode genaamd save die als ontvanger p neemt, een pointer naar Page. De methode neemt geen parameters aan en retourneert een waarde van het type error.”
Merk op dat de (p *Pagina) de volgende syntaxis heeft:
Deze methode slaat de body van de pagina op in een tekstbestand. Om het eenvoudig te houden gebruiken we de Titel als bestandsnaam.
De save-methode retourneert een foutwaarde omdat dat het return-type is van WriteFile (een standaard bibliotheek functie die een byte-schijf naar een bestand schrijft). De save methode retourneert de error waarde, om de applicatie dit te laten afhandelen mocht er iets fout gaan tijdens het schrijven van het bestand. Als alles goed gaat, retourneert Page.save() nil (de nul-waarde voor pointers, interfaces, en sommige andere typen).
Het octale gehele getal 0600, doorgegeven als derde parameter aan WriteFile, geeft aan dat het bestand moet worden aangemaakt met alleen lees-schrijf-rechten voor de huidige gebruiker.
Naast het opslaan van pagina’s willen we ook pagina’s laden:
func loadPage(title string) *Page { filename := title + ".txt" body, _ := ioutil.ReadFile(filename) return &Page{Title: title, Body: body}}
De functie loadPage stelt de bestandsnaam samen uit de parameter title, leest de inhoud van het bestand in een nieuwe variabele body, en retourneert een pointer naar een Page-literaal dat is samengesteld met de juiste waarden voor titel en body.
Functies kunnen meerdere waarden retourneren. De standaard bibliotheek functie io.ReadFile retourneert byte en error. In loadPage wordt de fout nog niet behandeld; de “blank identifier”, vertegenwoordigd door het underscore (_)-symbool, wordt gebruikt om de foutretourwaarde weg te gooien (in wezen wordt de waarde aan niets toegewezen).
Maar wat gebeurt er als ReadFile op een fout stuit? Bijvoorbeeld, het bestand zou niet kunnen bestaan. Zulke fouten mogen we niet negeren. Laten we de functie zo wijzigen dat *Pagina en fout worden geretourneerd.
func loadPage(title string) (*Page, error) { filename := title + ".txt" body, err := ioutil.ReadFile(filename) if err != nil { return nil, err } return &Page{Title: title, Body: body}, nil}
Aanroepers van deze functie kunnen nu de tweede parameter controleren; als deze nihil is, is met succes een Pagina geladen. Zo niet, dan zal het een fout zijn die door de aanroeper kan worden afgehandeld.
Op dit punt hebben we een eenvoudige gegevensstructuur en de mogelijkheid om op te slaan in en te laden uit een bestand. Laten we een hoofdfunctie schrijven om te testen wat we hebben geschreven:
func main() { p1 := &Page{Title: "TestPage", Body: byte("This is a sample Page.")} p1.save() p2, _ := loadPage("TestPage") fmt.Println(string(p2.Body))}
Na het compileren en uitvoeren van deze code is een bestand met de naam TestPage.txt aangemaakt, dat de inhoud van p1 bevat. Het bestand wordt vervolgens ingelezen in de struct p2, en het element Body wordt afgedrukt op het scherm.
Laten we beginnen met een eenvoudige webserver, een soortgelijke als die we eerder hebben gedaan (Web):
De hoofdfunctie begint met een oproep aan http.HandleFunc, dat het http-pakket vertelt om alle verzoeken aan de webroot (“/”) af te handelen met handler.
Hij roept dan http.ListenAndServe aan, waarbij hij specificeert dat hij moet luisteren op poort 8080 op een willekeurige interface (“:8080”). (Maak je voorlopig geen zorgen over de tweede parameter, nihil.) Deze functie zal blokkeren totdat het programma wordt beëindigd.
ListenAndServe() retourneert altijd een fout, omdat het alleen retourneert wanneer een onverwachte fout optreedt. Om die fout te loggen omwikkelen we de functie-aanroep met log.Fatal. De Fatal functie roept os.Exit(1) op na het schrijven van het log bericht.
De functie handler is van het type http.HandlerFunc. Het neemt een http.ResponseWriter en een http.Request als argumenten.
Een http.ResponseWriter waarde assembleert het HTTP server antwoord; door er naar te schrijven, sturen we data naar de HTTP client.
Een http.Request is een data structuur die het client HTTP verzoek representeert. r.URL.Path is de path component van de request URL. De trailing betekent “maak een deel van Path vanaf het 1e teken tot het einde.” Dit laat de leidende “/” uit de padnaam weg.
Uitvoeren van dit programma en toegang krijgen tot de URL:
Doorgaan naar Web Applicatie Deel 2 (Gebruik van net/http).
- GoLang tutorial – HelloWorld
- Workspaces
- Visual Studio Code
- Data Types and Variables
- byte and rune
- Packages
- Functions
- Arrays en Slices
- Een functie die een slice neemt en retourneert
- Conditionals
- Lussen
- Maps
- Range
- Pointers
- Closures and Anonymous Functions
- Structs and receiver methods
- Value or Pointer Receivers
- Interfaces
- Web Application Part 0 (Introduction)
- Web Applicatie Deel 1 (Basis)
- Web Applicatie Deel 2 (Gebruik van net/http)
- Web Applicatie Deel 3 (Toevoegen van “edit” mogelijkheid)
- Web Applicatie Deel 4 (Behandeling van nietbestaande pagina’s en opslaan van pagina’s)
- Web Applicatie Deel 5 (Foutafhandeling en template caching)
- Web Applicatie Deel 6 (Valideren van de titel met een reguliere expressie)
- Web Applicatie Deel 7 (Function Literals en Closures)
- Bouwen van Docker image en uitrollen van Go applicatie naar een Kubernetes cluster (minikube)
- Serverless Framework (Serverless Application Model-SAM)
- Serverloze Web API met AWS Lambda
- Arrays vs Slices met een array links rotatie sample
- Variadic Functions
- Goroutines
- Channels (”
- Channels (”
- Channels (”
- Defer
- GoLang Paniek en Herstel
- String Opmaak
- JSON
- SQLite
- Modules 1 (Een nieuwe module maken)
- Modules 2 (Afhankelijkheden toevoegen)
- AWS SDK for Go (S3 listing)
- Linked List
- Binary Search Tree (BST) Part 1 (Boom/Node structs met insert en print functies)