Mise en place GORM
go get -u gorm.io/gorm
go get -u gorm.io/driver/postgres
package main
import (
"fmt"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"log"
)
var DB *gorm.DB
func initDatabase() {
dsn := "host=localhost user=gormuser password=gormpassword dbname=gormdb port=5432 sslmode=disable TimeZone=Europe/Paris"
var err error
DB, err = gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatal("Failed to connect to database: ", err)
}
fmt.Println("Database connected successfully!")
}
func main() {
initDatabase()
}
type User struct {
ID uint `gorm:"primaryKey"`
Name string
Email string `gorm:"unique"`
Password string
}
func migrate() {
DB.AutoMigrate(&User{})
fmt.Println("Database migrated!")
}
func main() {
initDatabase()
migrate()
}
func createUser(name string, email string, password string) {
user := User{Name: name, Email: email, Password: password}
DB.Create(&user)
fmt.Printf("User %s created successfully!\n", user.Name)
}
// Dans main
createUser("John Doe", "john@example.com", "securepassword")
func getUsers() {
var users []User
DB.Find(&users)
for _, user := range users {
fmt.Printf("User: %s, Email: %s\n", user.Name, user.Email)
}
}
func updateUserEmail(id uint, newEmail string) {
var user User
DB.First(&user, id)
user.Email = newEmail
DB.Save(&user)
fmt.Printf("User %s updated with new email: %s\n", user.Name, user.Email)
}
// Dans main
updateUserEmail(1, "john.doe@newemail.com")
func deleteUser(id uint) {
var user User
DB.Delete(&user, id)
fmt.Printf("User with ID %d deleted successfully!\n", id)
}
// Dans main
deleteUser(1)
Mise en place Golang avec Redis
# Executer redis
docker run --name redis-cache -d -p 6379:6379 redis
# Executer redis-cli
docker exec -it redis-cache redis-cli ping
# Créer le repo
mkdir go-redis-cache
cd go-redis-cache
go mod init go-redis-cache
# Gin-Gonic
go get -u github.com/gin-gonic/gin
go get -u github.com/go-redis/redis/v8
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
"context"
"github.com/go-redis/redis/v8"
"time"
)
var ctx = context.Background()
func main() {
r := gin.Default()
// Connecter Redis
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // Pas de mot de passe par défaut
DB: 0, // Utiliser la base de données par défaut
})
// Route pour obtenir une donnée
r.GET("/data/:key", func(c *gin.Context) {
key := c.Param("key")
// Vérifier si la donnée est en cache
val, err := rdb.Get(ctx, key).Result()
if err == redis.Nil {
// Simuler une récupération lente de la donnée depuis la base de données
time.Sleep(2 * time.Second)
val = fmt.Sprintf("Data for key %s", key)
// Stocker la donnée dans Redis avec une durée d'expiration
err := rdb.Set(ctx, key, val, 10*time.Second).Err()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to cache data"})
return
}
} else if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to retrieve data"})
return
}
// Retourner la donnée (du cache ou de la "base de données")
c.JSON(http.StatusOK, gin.H{"data": val})
})
// Démarrer le serveur HTTP
r.Run(":8080")
}
Mise en place Gin-Gonic
go get -u github.com/gin-gonic/gin
package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
// Définir une route GET
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
// Démarrer le serveur sur le port 8080
r.Run(":8080")
}
go run main.go
// Création de routes et gestion des requêtes
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
var users = []string{"Alice", "Bob", "Charlie"}
func main() {
r := gin.Default()
// Route pour obtenir tous les utilisateurs
r.GET("/users", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"users": users,
})
})
// Route pour ajouter un utilisateur
r.POST("/users", func(c *gin.Context) {
var newUser string
if err := c.BindJSON(&newUser); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid data"})
return
}
users = append(users, newUser)
c.JSON(http.StatusCreated, gin.H{"user": newUser})
})
// Démarrer le serveur
r.Run(":8080")
}
func LoggerMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
fmt.Println("Request received: ", c.Request.Method, c.Request.URL)
c.Next()
}
}
func main() {
r := gin.Default()
// Utiliser le middleware de journalisation
r.Use(LoggerMiddleware())
// Définir des routes...
r.Run(":8080")
}
r.POST("/users", func(c *gin.Context) {
var newUser string
if err := c.BindJSON(&newUser); err != nil || newUser == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user data"})
return
}
users = append(users, newUser)
c.JSON(http.StatusCreated, gin.H{"user": newUser})
})
r.GET("/error", func(c *gin.Context) {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Something went wrong"})
})
package main
import (
"bytes"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
"net/http"
"net/http/httptest"
"testing"
)
func TestGetUsers(t *testing.T) {
// Configurer Gin en mode test
r := gin.Default()
// Route de test
r.GET("/users", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"users": users,
})
})
// Créer une requête HTTP
req, _ := http.NewRequest("GET", "/users", nil)
w := httptest.NewRecorder()
r.ServeHTTP(w, req)
// Assertions
assert.Equal(t, http.StatusOK, w.Code)
assert.Contains(t, w.Body.String(), "Alice")
}
func TestPostUser(t *testing.T) {
// Configurer Gin en mode test
r := gin.Default()
// Route de test
r.POST("/users", func(c *gin.Context) {
var newUser string
if err := c.BindJSON(&newUser); err != nil || newUser == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user data"})
return
}
users = append(users, newUser)
c.JSON(http.StatusCreated, gin.H{"user": newUser})
})
// Créer une requête HTTP
user := `"David"`
req, _ := http.NewRequest("POST", "/users", bytes.NewBufferString(user))
req.Header.Set("Content-Type", "application/json")
w := httptest.NewRecorder()
r.ServeHTTP(w, req)
// Assertions
assert.Equal(t, http.StatusCreated, w.Code)
assert.Contains(t, w.Body.String(), "David")
}
go test
Mise en place d'un service GRPC
apt install protobuf-compiler
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.26
ENV :
GO_MOD = monpacket
PROTOBUF_DIR = ./proto
---
Commands :
protoc --experimental_allow_proto3_optional \
--go_out=src --go_opt=paths=source_relative --go_opt=Mprotos_ext/lameduse-utils-image_manager-v1.proto=$(GO_MOD)/protos protos/pb.proto \
--go-grpc_out=src --go-grpc_opt=paths=source_relative --go-grpc_opt=Mprotos_ext/lameduse-utils-image_manager-v1.proto=$(GO_MOD)/protos protos/pb.proto
syntax = "proto3";
package v1.service.core.lameduse;
option go_package = "monpacket/protos";
enum Status {
NO_STATUS = 0; // No status / Unknow
OK = 1; // Request is ok
ERROR_INTERNAL = 2; // Request failed because of an internal error
ERROR_ACCESS = 3; // Request failed because access is denied
ERROR_EXIST = 4; // Request failed because ressource already exist
ERROR_PARAMS = 5; // Request failed because params are incorrect
}
/// TAG Manager Service
service TagManager {
rpc CreateTag(TagCreateRequest) returns (TagCreateResponse); // Create an new tag
rpc ListTag(TagListRequest) returns (TagListResponse); // List existing tags with partial
}
message Tag {
uint64 id = 1;
string name = 2;
}
message TagCreateRequest {
string name = 1; // Name of the tag to create
}
message TagCreateResponse {
bool ok = 1; // if ok == true request was successful
Status status = 2; // Return the status
}
message TagListRequest {
string partial = 1; // Partial name of the tag
}
message TagListResponse {
bool ok = 1; // if ok == true request was successful
repeated string tags = 2; // Return the matching tags
}
/// Collection Manager Service
service CollectionManager {
rpc CreateCollection(CollectionCreateRequest) returns (CollectionCreateResponse); // Create an new collection
rpc ListCollection(CollectionListRequest) returns (CollectionListResponse); // List existing collection with partials
rpc GetCollection(CollectionGetRequest) returns (CollectionGetResponse); // Get a collection
rpc UpdateCollection(CollectionUpdateRequest) returns (CollectionUpdateResponse); // Update a collection
}
message CollectionObject {
uint64 id = 1; // ID of the collection
string name = 2; // Name of the collection
}
message CollectionCreateRequest {
string name = 1; // Name of the collection to create
}
message CollectionCreateResponse {
bool ok = 1; // if ok == true request was successful
Status status = 2; // Return the status
uint64 id = 3; // Return the collection ID
}
message CollectionListRequest {
string partial = 1; // Partial name of the collection
}
message CollectionListResponse {
bool ok = 1; // if ok == true request was successful
repeated CollectionObject collections = 2; // Return the matching collection ids
}
message CollectionGetRequest {
uint64 id = 1; // ID of the collection
}
message CollectionGetResponse {
bool ok = 1; // if ok == true request was successful
CollectionObject collection = 2; // Return the collection
}
message CollectionUpdateRequest {
uint64 id = 1; // ID of the collection
string name = 2; // Name of the collection
}
message CollectionUpdateResponse {
bool ok = 1; // if ok == true request was successful
Status status = 2; // Return the status
}
service CollectionItemManager {
rpc CreateCollectionItem(CollectionItemCreateRequest) returns (CollectionItemCreateResponse); // Create an new collection
rpc ListCollectionItem(CollectionItemListRequest) returns (CollectionItemListResponse); // List existing collection with partials
rpc GetCollectionItem(CollectionItemGetRequest) returns (CollectionItemGetResponse); // Get a collection
rpc UpdateCollectionItem(CollectionItemUpdateRequest) returns (CollectionItemUpdateResponse); // Update a collection
rpc DeleteCollectionItem(CollectionItemDeleteRequest) returns (CollectionItemDeleteResponse); // Delete a collection
}
message CollectionItemObject {
uint64 id = 1;
string name = 2;
uint64 image_id = 3;
uint64 collection_id = 4;
}
message CollectionItemCreateRequest {
CollectionItemObject item = 1;
}
message CollectionItemCreateResponse {
bool ok = 1; // if ok == true request was successful
Status status = 2; // Return the status
uint64 id = 3; // Return the collection ID
}
message CollectionItemListRequest {
uint64 collection_id = 1;
}
message CollectionItemListResponse {
bool ok = 1; // if ok == true request was successful
repeated CollectionItemObject items = 2; // Return the matching collection ids
Status status = 3; // Return the status
}
message CollectionItemGetRequest {
uint64 id = 1; // ID of the collection
}
message CollectionItemGetResponse {
bool ok = 1; // if ok == true request was successful
CollectionItemObject item = 2; // Return the collection
Status status = 3; // Return the status
}
message CollectionItemUpdateRequest {
CollectionItemObject item = 1;
}
message CollectionItemUpdateResponse {
bool ok = 1; // if ok == true request was successful
Status status = 2; // Return the status
}
message CollectionItemDeleteRequest {
uint64 id = 1; // ID of the collection
}
message CollectionItemDeleteResponse {
bool ok = 1; // if ok == true request was successful
Status status = 2; // Return the status
}
service ImageManager {
rpc List(ImageListRequest) returns (ImageListResponse); // Get images
}
message ImageCreateRequest {
string name = 1;
}
message ImageCreateResponse {
bool ok = 1; // if ok == true request was successful
Status status = 2; // Return the status
uint64 id = 3; // Return the image ID
}
message ImageListRequest {
}
message ImageListResponse {
bool ok = 1; // if ok == true request was successful
repeated string ids = 2; // Return the matching collection ids
}
service UserManager {
rpc UserCreate(UserCreateRequest) returns (UserCreateResponse);
rpc UserLogin(UserLoginRequest) returns (UserLoginResponse);
rpc UserGet(UserGetRequest) returns (UserGetResponse);
rpc UserUpdate(UserUpdateRequest) returns (UserUpdateResponse);
}
message UserObject {
string id = 1;
string email = 2;
string phone = 3;
string firstname = 4;
string lastname = 5;
bool email_ok = 6;
string raw_password = 8;
string hash_password = 9;
string key = 10;
bool role_admin = 11;
bool role_factory = 12;
bool role_customer_individual = 13;
bool role_customer_business = 14;
string info_address1 = 17;
string info_address2 = 18;
string info_city = 19;
string info_region = 20;
string into_city_code = 21;
string info_contry = 22;
string info_business_localid = 23;
string info_business_vatid = 24;
string info_business_name = 25;
}
message UserCreateRequest {
string email = 2;
string raw_password = 3;
}
message UserCreateResponse {
bool ok = 1; // if ok == true request was successful
Status status = 2; // Return the status
string message = 3; // message for the request
}
message UserLoginRequest {
string email = 2;
string raw_password = 3;
}
message UserLoginResponse {
bool ok = 1; // if ok == true request was successful
Status status = 2; // Return the status
string message = 3; // message for the request
string token = 4; // token for the user
}
message UserGetRequest {
string token = 2;
bool refresh_only = 3;
}
message UserGetResponse {
bool ok = 1; // if ok == true request was successful
Status status = 2; // Return the status
string message = 3; // message for the request
UserObject user = 4; // user object
string refresh_token = 5; // token for the user
}
message UserUpdateRequest {
string token = 1;
UserObject user = 2;
}
message UserUpdateResponse {
bool ok = 1; // if ok == true request was successful
Status status = 2; // Return the status
string message = 3; // message for the request
}