Top Go-Module: Golang-Web-APIs mit GORM
UPDATE: Am 1. Mai 2021 wird das zentrale Repository von GoCenter einschließlich aller Funktionen eingestellt. Weitere Informationen zur Einstellung der Center finden Sie im Blog-Beitrag zur Einstellung
Jeden Monat verleiht GoCenter den leistungsstärksten Modulen ein Gopher Badge als Auszeichnung für ihre Leistung. Wir schreiben über einige dieser Top-Module und wie sie in Go verwendet werden.
Robert Greiseimer hat Go als die Sprache des Cloud Computing bezeichnet. Es ist zwar kein Geheimnis, dass Go über starke Funktionen verfügt, die die Anforderungen von Microservice-Architekturen, verteilten Systemen und groß angelegten Unternehmensanwendungen unterstützen, aber was weniger bekannt ist, ist, dass Go von Anfang an auch mit Blick auf die Webentwicklung erstellt wurde. In der Tat verwenden viele Entwickler in der Community Go für die Full-Stack-Entwicklung und befürworten neue Module und Frameworks ein, die Go zu einer starken Sprache für das Web machen.
Werfen wir einen Blick auf einige der Möglichkeiten, wie Golang und die wachsende Welt der von der Community betriebenen Go-Module den Datenaustausch in Web-Apps unterstützen. Ich zeige auch, wie man mit GoCenter, dem kostenlosen Go-Modul-Proxy für die Entwicklergemeinde, einige wertvolle Module identifizieren kann, und werfe einen detaillierten Blick auf eines meiner Favoriten.
Golang liebt Daten im Web
Go verfügt über ausgefeilte Web-Pakete, die Teil seiner Kernbibliothek sind. Mit dem jüngsten Golang 1.15-Release wurde diese Kernbibliothek durch Verbesserungen an database/sql, database/sql/driver, net/http und encoding/json aktualisiert, sodass Go jetzt noch besser mit Web-Daten arbeiten kann. Diese Änderungen fügen Begrenzungen hinzu, die das Risiko einer Überbeanspruchung des Stapelspeichers durch große Mengen von Datendiensten verringern. Außerdem wurde eine Leerlaufzeit für Datenbankverbindungen festgelegt.
Web-Server-Erstellung
Go's net/http
-Paket von Go ist Teil der Standardbibliothek und dient dem Transport von HTML vom Server zum Client. Dies geschieht mit Hilfe einer http.Handler
-Schnittstelle, die ihren eigenen Webserver bildet. Diese Bibliothek macht die RESTful-API-Entwicklung sehr einfach, und mit Go structs können Big-Data-Anwendungen auf eine Reihe von verschiedenen Datenbanken und Datentypen abgebildet werden.
Zum Starten des Webdienstes müssen das net/http-Paket importiert und zwei Funktionen geschrieben werden.
package main
import (
"fmt"
"log"
"net/http"
)
func homePage(w http.ResponseWriter, r *http.Request){
fmt.Fprintf(w, "Willkommen auf der HomePage!")
fmt.Println("Endpunkt-Hit: homePage")
}
func handleRequests() {
http.HandleFunc("/", homePage)
log.Fatal(http.ListenAndServe(":10000", nil))
}
func main() {
handleRequests()
}
Mit dieser sehr einfachen Datei haben Sie einen funktionierenden Webserver eingerichtet. Dieser Server sendet, speichert und ruft natürlich nicht tatsächlich Informationen aus dem Web an eine Datenbank ab. Um diese Funktionalität einzubauen, würden wir eine grundlegende CRUD-Anwendung erstellen, die Informationen in Ihrer API ERSTELLEN, LESEN, AKTUALISIEREN und LÖSCHEN kann.
Weitere Details zur Verwendung dieses Pakets für die Erstellung von RESTful-APIs erfahren Sie in einem ausgezeichneten Tutorial von Elliot Forbes.
JSON
Eine Möglichkeit, Informationen zu senden und zu empfangen, ist die Verwendung der Kernbibliothek von Go encoding/json
. Diese Bibliothek macht es einfach, Daten aus JSON in Ihre Go-Anwendungen zu lesen/schreiben. JSON oder Javascript Object Notation wurde entwickelt, um Daten im Web zu kodieren bzw. zu dekodieren und ist viel besser für das Web geeignet als reines XML. Durch die Verwendung von key:value-Paaren liest sich JSON eher wie Klartext und sein lesbares Datenformat kann beim Aufbau Ihrer Full-Stack-Anwendungen auf eine Weise genutzt werden, die langwieriges SQL vermeidet. Während JSON das Senden von Daten einfach macht, wird weiterhin eine Möglichkeit benötigt, um mit einer Datenbank wie PostgreSQL zu sprechen.
Golang ORMs
Zum Glück hat die Go-Gemeinschaft eine Reihe von Object Relational Mapping-Bibliotheken (ORMs) entwickelt, die es Go-Entwicklern ermöglichen, JSON-key:value-Paarsyntax und-Kodierung zu verwenden, um direkt auf eine SQL-Datenbank wie PostgreSQL zu mappen. ORMs ermöglichen es Entwicklern, ihr natives Programmierparadigma zu verwenden, um Daten auf SQL zu mappen.
Ein ORM verwandelt Ihre Datenbankinformationen in Golang-Objekte und umgekehrt. Bei der Arbeit mit einem ORM können Sie, anstatt SQL-Abfragen direkt in Ihre Anwendung zu schreiben, Ihre Daten viel besser mit Golang struct wie in diesem Beispiel abbilden:
// User struct für meine Datenbank
type User struct {
gorm.Model
firstName string
lastName string
email string
message string
profession string
age int
zipCode int
}
Nicht jeder ist ein Fan der Verwendung von ORMs, weil sie eine Abstraktionsebene von den eigentlichen Daten in der Datenbank schaffen. Je nachdem, welche Bibliothek Sie verwenden, ist ein weiterer Nachteil, dass, während SQL langfristig bleibt, ORM-Frameworks über Nacht erscheinen und verschwinden können. Aber insgesamt habe ich festgestellt, dass ORMs es viel einfacher machen, die Daten einer Webanwendung in Go im Auge zu behalten und die Menge an langwieriger Codierung zu reduzieren, indem ich einen Haufen SQL-Befehle innerhalb meiner Anwendung gegen etwas austausche, das einfacher zu handhaben ist.
Es gibt eine Reihe von Go-ORMs, die in der Community unterstützt und gefördert werden und alle im GoCenter verfügbar sind:
- XORM: Ein einfaches und leistungsfähiges ORM-Framework für Go
- Go-PG: Ein postgreSQL-Client und ORM für Golang
- SQLBOILDER: Ein Tool zur Erzeugung eines auf Ihr Datenbankschema zugeschnittenen Go-ORM
- SQLX: Kein ORM, aber ein weiteres ausgezeichnetes Tool für SQL in Go
GORM: Ein Top-Gopher
GORM ist ein entwicklerfreundlicher ORM, der von Jinzhu Zhang entwickelt wurde, mehr als 19.000 Sterne auf GitHub hat, ausgezeichneten Support von der Community erhält und für den es eine leicht verständliche Dokumentation gibt. GORM ermöglicht CRUD-Operationen und kann auch für die anfängliche Migration und Erstellung des Datenbankschemas verwendet werden. Zu den weiteren Vorzügen von GORM gehören die Erweiterbarkeit mit nativer Plugin-Unterstützung, der Einsatz von Tests sowie 1:1- bzw. 1:n-Gruppen von Assoziationen Gorm unterstützt außerdem sqlite, mysql, postgres, and mssql.
- Die ReadMe des Moduls verweist Sie auf eine umfangreiche Dokumentation. Mehr Details über den Code des Moduls erfahren wir über die GoDoc-Registerkarte, die eine automatisch generierte Dokumentation von Funktionen und mehr zeigt.
- Die Used By– und Metrics-Registerkarten von GoCenter zeigen, dass dieses Modul angesichts vieler Downloads, Forks, Mitwirkenden und der Verwendung durch andere Go-Module beliebt und weithin vertrauenswürdig ist.
- Die Security-Registerkarte von GoCenter zeigt auch, dass die aktuelle Version dieses Moduls und seiner Abhängigkeiten keine bekannten NVD-Schwachstellen aufweisen, was durch einen JFrog Xray-Tiefenscan bestätigt wird.
GORM verwenden
Nehmen wir an, Sie wollten eine API (oder später eine Webanwendung) erstellen, die Benutzer auffordert, Ihnen ihren Namen, ihre E-Mail-Adresse und eine kurze Nachricht mitzuteilen. Mit GORM wäre es eine ziemlich einfache Reihe von Schritten, um dies in einer Datenbank abzubilden. Die Schritte:
- Einrichten Ihrer Datenbank
- Abbilden einer User struct
- Verbinden mit der db
- Anfängliche Migration auf die db
- Einrichten Ihrer Funktionen
- Ausführen der Anwendung
GORM Schritt für Schritt
Nehmen wir an, dass meine Teilzeit-Immobilienmaklerin (oder vielleicht meine Schwester) eine Webanwendung benötigt, die Anfragen zu Immobilien, die sie in unserer Heimatstadt verwaltet, sammeln und speichern kann. Das erste, was ich tun müsste, ist eine Datenbank zu entwickeln, die Benutzerinformationen speichern kann, sowie eine Web-API, die diese Informationen über ein Kontaktformular sammelt und später auf diese Benutzerinformationen zugreifen kann, damit sie in einem Browser gelesen werden können. Wir werden einige der wichtigsten Schritte durchgehen, die ich unternommen habe, um diese Art von Anwendung zu entwickeln.
Meine Module importieren
Zuerst können wir in unserer main.go-Datei unsere Module mit den folgenden Befehlen importieren:
$ export GOPROXY=https://gocenter.io
$ go get github.com/jinzhu/gorm
$ go get github.com/mattn/go-sqlite3
DB-Verbindungsvariable
Erstellen Sie eine einfache Variable für die GORM-Datenbank:
var db *gorm.DB
User Struct
Wir werden unsere Modelldefinition mit einer Golang struct erstellen, die den Namen des Benutzers, seine E-Mail und die Nachricht abbildet.
// User struct for my db
type User struct {
gorm.Model
name string
email string
message string
}
Anfängliche Migration für DB
Ich habe meine sqlite-Datenbank projekt.db genannt und kann die AutoMigrate-Funktion von GORM mit einer Funktion verwenden, die wie folgt aussieht:
// InitialMigration for project with db.AutoMigrate
func InitialMigration() {
db, err = gorm.Open("sqlite3", "project.db")
if err != nil {
fmt.Println(err.Error())
panic("Verbindung zur Datenbank fehlgeschlagen")
}
defer db.Close()
db.AutoMigrate(&User{})
}
Handler-Funktion anzeigen
Dadurch können wir die API-Daten im Browser sehen:
func viewHandler(writer http.ResponseWriter, request *http.Request) {
placeholder := []byte("Erfolgreich mit der Datenbank verbunden...")
_, err := writer.Write(placeholder)
check(err)
}
API-Funktion
Die API verwendet vier Hauptfunktionen, die es uns ermöglichen, Benutzer zu finden/zu bekommen, neue Benutzer hinzuzufügen, Benutzer zu löschen und Benutzerinformationen in der Datenbank zu aktualisieren. Diese können wie folgt umrissen werden:
- func allUsers
- func newUser
- func deleteUser
- func updateUser
Diese Funktion stellt z. B. eine Verbindung zur Datenbank her und zeigt alle Einträge für Benutzer an:
func allUsers(w http.ResponseWriter, r *http.Request) {
db, err := gorm.Open("sqlite3", "projekt.db")
if err != nil {
panic("Verbindung zur Datenbank fehlgeschlagen")
}
defer db.Close()
var users []Benutzer
db.Find(&users)
fmt.Println("{}", users)
json.NewEncoder(w).Encode(users)
}
Router
Nachdem jede der obigen Funktionen erstellt wurde, würde die Funktion für das Routing wie folgt aussehen:
func handleRequests() {
myRouter := mux.NewRouter().StrictSlash(true)
myRouter.HandleFunc("/users", allUsers).Methods("GET")
myRouter.HandleFunc("/user/{name}", deleteUser).Methods("DELETE")
myRouter.HandleFunc("/user/{name}/{email}", updateUser).Methods("PUT")
myRouter.HandleFunc("/user/{name}/{email}", newUser).Methods("POST")
myRouter.HandleFunc("/user/{name}/{email}/{message}", updateUser).Methods("PUT")
myRouter.HandleFunc("/user/{name}/{email}/{message}", newUser).Methods("POST")
log.Fatal(http.ListenAndServe(":8081", myRouter))
}
Hauptfunktion
Zuletzt können Sie die Anwendung ausführen, indem Sie Folgendes in Ihrer Hauptfunktion platzieren:
func main() {
fmt.Println("GORM API-Projekt gestartet")
initialMigration()
handleRequests()
}
Anwendung ausführen
Dann werden wir unter Verwendung von go run main.go
, die Reaktion sehen:
GORM-API-Projekt gestartet
Und wenn ich ein paar Anfragen an meine API POSTE, kann ich diese Anfrage BEKOMMEN und die Daten im Browser sehen:
Tiefer in das Thema eintauchen
Als Go-Entwickler, der GORM zum ersten Mal verwendet, war die Migration und das Mapping von Daten in eine Sqlite-Datenbank sehr einfach. Der obige Code ist nur eine Momentaufnahme, um Ihnen den Einstieg zu erleichtern.
Weitere Informationen zur Verwendung von GORM zur Erstellung von APIs finden Sie indiesem ausgezeichneten und umfassenden Tutorial mit Video von Elliot Forbes. Vergessen Sie nicht, sich bei Elliot auf Twitter für sein wunderbares Tutorial zu bedanken, das jeden Aspekt der Golang-APIs beleuchtet.
GORM v2 ist nun ebenfalls veröffentlicht und wird für öffentliche Tests verwendet.
Fazit
Zu den Stärken von Go in der Web-API-Entwicklung gehören seine Geschwindigkeit und Skalierbarkeit, was im Zeitalter des Machine Learning ziemlich wichtig ist. Go wurde in der Ära der Mehrkernprozessoren entwickelt und verwendet Goroutinen, um Aufgaben gleichzeitig durch mehrere Kanäle auf mehreren CPUs zu führen. Das bedeutet, dass es die Skalierung und Infrastruktur bewältigen kann, die für große Datenanwendungen erforderlich ist, und Millionen von HTTP-Anfragen gleichzeitig verarbeiten kann. Außerdem ist es statisch typisiert und seine strenge Syntax macht es viel einfacher, Fehler zu debuggen und zu verhindern, die weniger strenge Sprachen mit riesigen Bibliotheken wie Javascript einführen könnten. Aus diesem Grund haben sich Unternehmen von Uber bis DropBox als Sprache der Wahl für APIs und zur Skalierung ihrer webfähigen Anwendungen für Go entschieden.
Sollten Sie die API-Fähigkeiten von Go ausprobieren wollen, ist die Erstellung einer eigenen Web-API mit ORMs wie GORM ein guter Anfang.