Implementierung der API zum Umschalten von Werten auf zwei Arten (go)

Dinge die zu tun sind

Der Zweck ist zu üben, Go's Web Framework Echo zu werden. Selbst wenn Sie den Wert umschalten, gibt es meiner Meinung nach Fälle, in denen der Bool-Wert der Datenbank auf true <=> false gesetzt ist, und Fälle, in denen Datensätze in der Datenbank eingefügt oder gelöscht werden (z. B. das Erstellen einer bevorzugten Funktion mithilfe einer Zwischentabelle). .. Dieses Mal werden wir nach der Implementierung des ersteren als BoolToggler-Modell das letztere implementieren, indem wir dem Benutzermodell eine Lieblingsfunktion für BoolToggler hinzufügen. (Es ist eine surreale und unpraktische Anwendung, aber es ist eine Praxis, also ist es mir egal ...) Ich habe den gesamten Code auf GitHub gestellt.

API zum Umschalten des Bool-Werts von DB

models

Dies ist das Hauptthema 1 dieses Artikels. Aktivieren Sie True <=> False für einen Spaltenwert vom Typ bool im Modell. Ich habe ein solches Modell definiert und bin migriert.

models/bool_toggler.go

package models

import (
    "github.com/jinzhu/gorm"
)

type BoolToggler struct {
	// type gorm.Model struct {
			// ID        uint           `gorm:"primaryKey"`
			// CreatedAt time.Time
			// UpdatedAt time.Time
			// DeletedAt gorm.DeletedAt `gorm:"index"`
	// }
  gorm.Model
  Toggler bool `json:"toggler"`
}

Es ist eine Struktur mit einem einfachen Bool-Wert namens Toggler. Implementieren Sie den API-Teil.

Implementierung der API

web/api/toggle_bool_toggler.go

package api

import (
	"github.com/labstack/echo"
	"github.com/valyala/fasthttp"
	"strconv"
	"hello/models"
	"hello/middlewares"
)

func ToggleBoolToggler() echo.HandlerFunc {
	return func(c echo.Context) error {
        //DB-Verbindungs-Middleware
		dbs := c.Get("dbs").(*middlewares.DatabaseClient)
		//Da der Pfadparameter Zeichenfolge ist, konvertieren Sie ihn in uint
		intId, _ := strconv.Atoi(c.Param("id"))
		uintId := uint(intId)

		boolToggler := models.BoolToggler{}
		if dbs.DB.First(&boolToggler, uintId).RecordNotFound() {
			//Wenn die ID falsch angegeben ist, wird der Statuscode 404 zurückgegeben.
			return c.JSON(fasthttp.StatusNotFound, "Der boolToggler mit der angegebenen ID wurde nicht gefunden.")
		} else {
			//Bool-Wert umkehren und speichern
			boolToggler.Toggler = !boolToggler.Toggler
			dbs.DB.Save(&boolToggler)
			return c.JSON(fasthttp.StatusOK, boolToggler)
		}
	}
}

Endpunkt, der den aktuell konfigurierten Toggler zurückgibt

web/api/get_bool_toggler.go

package api

import (
	"github.com/labstack/echo"
	"github.com/valyala/fasthttp"
	"hello/models"
	"hello/middlewares"
	"strconv"
)

func GetBoolToggler() echo.HandlerFunc {
	return func(c echo.Context) error {
		dbs := c.Get("dbs").(*middlewares.DatabaseClient)
		intId, _ := strconv.Atoi(c.Param("id"))
		uintId := uint(intId)

		boolToggler := models.BoolToggler{}
		if dbs.DB.First(&boolToggler, uintId).RecordNotFound() {
			return c.JSON(fasthttp.StatusNotFound, "Der boolToggler mit der angegebenen ID wurde nicht gefunden.")
		} else {
			return c.JSON(fasthttp.StatusOK, boolToggler.Toggler)
		}
	}
}

Es ist im Grunde das gleiche wie zuvor. Anstatt die Daten zu aktualisieren, rufe ich einfach die Booleschen Werte ab und füge sie in die Antwort ein.

routes/api.go

func Init(e *echo.Echo) {
	g := e.Group("/api")
    {
        g.PUT("/bool_toggler/:id/toggle", api.ToggleBoolToggler())
        g.GET("/bool_toggler/:id", api.GetBoolToggler()) 
    }
}

Lassen Sie uns die bisherige Operation testen.

curl http://localhost:8080/api/bool_toggler/1
>> false

curl -XPUT http://localhost:8080/api/bool_toggler/1/toggle
>> {"ID":1,"CreatedAt":"2020-10-05T14:54:27Z","UpdatedAt":"2020-10-07T10:49:12.1435735Z","DeletedAt":null,"toggler":true}

curl http://localhost:8080/api/bool_toggler/1
>> true

//Nicht registrierte Daten
curl http://localhost:8080/api/bool_toggler/3
>> "Der boolToggler mit der angegebenen ID wurde nicht gefunden.

Ich konnte bestätigen, dass es gut funktionierte.

API zum Umschalten des Lieblingsstatus

models

Wir werden eine API implementieren, die Werte löscht und in die Daten einfügt, die die Beziehung in der Zwischentabelle ausdrücken.

Wir beginnen mit der Erstellung eines einfachen Benutzermodells. Da der Zweck darin besteht, relationale Viele-zu-Viele-Daten als einfache Anwendung mit einer Zwischentabelle zu implementieren, erstellen wir keine Authentifizierungsfunktion. Auf jeden Fall ist es ein Modell mit nur einem Zeitstempel und einem Namen. Migrieren Sie auf die gleiche Weise.

Https://gorm.io/ja_JP/docs/many_to_many.html, um mit GORM eine Viele-zu-Viele-Datenbank zu erstellen

models/user.go

package models

import (
  "github.com/jinzhu/gorm"
)

type User struct {
	gorm.Model
	name string `json:"name"`
	//Bool mit dem Namen Favoriten_Togler aufbewahren
	Favorites []*BoolToggler `gorm:"many2many:user_favorite_togglers;"`
}

API-Implementierung

URI-Design zuerst, aber weil es keine Authentifizierungsfunktion gibt

/api/favorite/users/:user_id/bool_togglers/:toggler_id

Sie können sehen, dass es notwendig ist, mit dem URI aus mehreren Pfadparametern auf jede Entität zu verweisen. Das Folgende ist der API-Teil, aber da er ziemlich kompliziert geworden ist, habe ich viele Kommentare hinterlassen

web/api/toggle_favorite_bool_toggler.go

package api

import (
	"github.com/labstack/echo"
	"github.com/valyala/fasthttp"
	"strconv"
	"hello/models"
	"hello/middlewares"
)

func ToggleFavoriteToggler() echo.HandlerFunc {
	return func(c echo.Context) error {

		//Struktur, die JSON für die Antwort erstellt
		type Response struct {
			UserId         uint
			BoolTogglerId  uint
			Favorite       bool
		}

		//DB-Verbindung
		dbs := c.Get("dbs").(*middlewares.DatabaseClient)
		
		//Konvertieren Sie Pfadparameter in uint
		intUserId, _ := strconv.Atoi(c.Param("user_id"))
		uintUserId := uint(intUserId)
		intTogglerId, _ := strconv.Atoi(c.Param("toggler_id"))
		uintTogglerId := uint(intTogglerId)

		//Sofortige Antwortstruktur
		var resJSON Response
		resJSON.UserId = uintUserId
		resJSON.BoolTogglerId = uintTogglerId

		//Übergeben Sie den boolToggler beim Anhängen mit der angegebenen ID
		var boolToggler models.BoolToggler
		boolToggler.ID = uintTogglerId
		
		//Aktivieren Sie Benutzerbeziehungen in Preload und wählen Sie
		user := &models.User{}
		dbs.DB.Preload("Favorites", "bool_toggler_id = ?", uintTogglerId).
		Find(&user, uintUserId)

		//Fügen Sie einen neuen Datensatz hinzu, falls dieser noch nicht favorisiert wurde
		if len(user.Favorites) < 1 {
			dbs.DB.Model(&user).Association("Favorites").Append(&boolToggler)
			resJSON.Favorite = true

		//Löschen Sie den vorhandenen Datensatz, wenn er bevorzugt wurde
		} else {
			dbs.DB.Model(&user).Association("Favorites").Delete(&boolToggler)
			resJSON.Favorite = false
		}
		return c.JSON(fasthttp.StatusOK, resJSON)
	}
}

routes/api.go

g.POST("/favorite/users/:user_id/bool_togglers/:toggler_id", api.ToggleFavoriteToggler()) //Nachtrag

Wenn ich Curl versuche, wird der Wert richtig umgeschaltet.

curl -XPOST http://localhost:8080/api/favorite/users/1/bool_togglers/1
{"UserId":1,"BoolTogglerId":1,"Favorite":false}
/go/src/app # curl -XPOST http://localhost:8080/api/favorite/users/1/bool_togglers/1
{"UserId":1,"BoolTogglerId":1,"Favorite":true}

Als ich die MySQL-Tabelle überprüfte, konnte ich außerdem das beabsichtigte Verhalten bestätigen.

mysql> select * from user_favorite_togglers;
+---------+-----------------+
| user_id | bool_toggler_id |
+---------+-----------------+
|       1 |               1 |
+---------+-----------------+
1 row in set (0.00 sec)

//Nach dem Zugriff
mysql> select * from user_favorite_togglers;
Empty set (0.00 sec)

Endpunkt, der Benutzerinformationen zurückgibt

web/api/show_user.go

package api

import (
	"github.com/labstack/echo"
	"github.com/valyala/fasthttp"
	"hello/models"
	"hello/middlewares"
	"strconv"
)

func ShowUserInfo() echo.HandlerFunc {
	return func(c echo.Context) error {

		type ResToggler struct {
			BoolTogglerId uint
			Toggler       bool
		}

		type Response struct {
			UserId uint
			Name   string
			Favorites []ResToggler
		}

		dbs := c.Get("dbs").(*middlewares.DatabaseClient)
		//Konvertieren Sie Pfadparameter in uint
		intUserId, _ := strconv.Atoi(c.Param("id"))
		uintUserId := uint(intUserId)
		
		//Aktivieren Sie Benutzerbeziehungen in Preload und wählen Sie
		user := models.User{}
		dbs.DB.Preload("Favorites").Find(&user, uintUserId)

		var resJSON Response
		resJSON.UserId = user.ID
		resJSON.Name   = user.Name
		for _, v := range user.Favorites {
			toggler := ResToggler{
				BoolTogglerId: v.ID,
				Toggler: v.Toggler,
			}
			resJSON.Favorites = append(resJSON.Favorites, toggler)
		}
		return c.JSON(fasthttp.StatusOK, resJSON)
	}
}

Das Schöne am Echo-Framework ist, dass Sie eine Struktur für Response so wie sie ist als JSON übergeben können. Das Ergebnis gibt eine Struktur wie folgt zurück:

curl http://localhost:8080/api/user/1
{"UserId":1,"Name":"test_user01","Favorites":[{"BoolTogglerId":1,"Toggler":false}]}

Recommended Posts

Implementierung der API zum Umschalten von Werten auf zwei Arten (go)
Ich habe zwei Möglichkeiten ausprobiert, um mehrere Commits mit Git zu kombinieren
Zwei Möglichkeiten, mit matplotlib mehrere Grafiken in einem Bild anzuzeigen
Eine verwirrende Geschichte mit zwei Möglichkeiten, XGBoost in Python + zu implementieren
3 Möglichkeiten, Zeitzeichenfolgen mit Python zu analysieren [Hinweis]
Minimale Implementierung von Union Find in Python
Zwei Möglichkeiten, binäre Vektorkacheln in GeoJSON zu dekodieren
Beispiel-API-Server, der JSON in Golang empfängt
So erstellen Sie eine Rest-API in Django