Golang Basics Crud
Absolutely! Let's get started. Here's how we'll modify the project to add CRUD operations, user registration, and secure everything with PostgreSQL and JWT.
Prerequisites
- Basic understanding of SQL and how to work with databases.
- PostgreSQL installed and running on your system.
1. Set up PostgreSQL Database
- Create a Database: Use a tool like pgAdmin or the
psql
command-line tool to create a database (e.g.,go_fiber_api_db
). - Create a User Table:
CREATE TABLE users ( id SERIAL PRIMARY KEY, username VARCHAR(50) UNIQUE NOT NULL, password VARCHAR(255) NOT NULL -- Store hashed password! );
2. Install PostgreSQL Driver
go get -u github.com/jackc/pgx/v4/stdlib
3. Modify Models (models/user.go
)
package models
// User model representing the database table
type User struct {
ID int `json:"id"`
Username string `json:"username"`
Password string `json:"password"` // Don't expose in API responses
}
4. Database Connection (utils/db.go
)
package utils
import (
"context"
"fmt"
"log"
"github.com/jackc/pgx/v4/pgxpool"
)
var db *pgxpool.Pool // Global database connection pool
func ConnectDB() {
// Read database credentials from environment variables
dbURL := fmt.Sprintf("postgres://user:password@localhost:5432/go_fiber_api_db")
var err error
db, err = pgxpool.Connect(context.Background(), dbURL)
if err != nil {
log.Fatalf("Unable to connect to database: %v\n", err)
}
}
5. Authentication Functions (controllers/auth.go
)
package controllers
import (
// ... other imports ...
"golang.org/x/crypto/bcrypt" // For password hashing
)
// Register creates a new user
func Register(c *fiber.Ctx) error {
var user models.User
if err := c.BodyParser(&user); err != nil {
return err
}
// Hash password
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost)
if err != nil {
return err
}
user.Password = string(hashedPassword)
// Insert user into database
_, err = utils.db.Exec(c.Context(), "INSERT INTO users (username, password) VALUES ($1, $2)", user.Username, user.Password)
if err != nil {
return c.Status(500).SendString(err.Error())
}
// ... Generate JWT and respond ... (similar to earlier example)
return c.JSON(fiber.Map {"message": "User created"})
}
// Login authenticates and generates a JWT
func Login(c *fiber.Ctx) error {
// ... Logic similar to earlier example, but fetch user
// from the database and compare hashed passwords ...
}
6. CRUD Functions (Example - controllers/products.go
)
// ... other controllers code
// CreateProduct adds a new product (requires auth)
func CreateProduct(c *fiber.Ctx) error {
// ... Authenticate user (using middleware) ...
var product models.Product
if err := c.BodyParser(&product); err != nil {
return err
}
// Insert product into database
_, err = db.Exec(c.Context(), "INSERT INTO products (name, price) VALUES ($1, $2)", product.Name, product.Price)
if err != nil {
return c.Status(500).SendString(err.Error())
}
return c.JSON(fiber.Map{"message": "Product created"})
}
7. Update main.go
- Call
utils.ConnectDB()
to establish the database connection.