Berikut adalah proyek sederhana yang terdiri dari frontend (React.js) dan backend (Go dengan Fiber) untuk aplikasi todo-list yang bisa melakukan operasi read, create, dan delete dengan PostgreSQL sebagai basis datanya.
Struktur Folder
Copy todo-frontend/
├── public
│ └── index.html
├── src
│ ├── App.js
│ ├── index.js
│ ├── components
│ │ └── ProductList.js
├── package.json
└── .env
todo-backend/
├── main.go
├── go.mod
├── go.sum
└── database
└── connection.go
todo-frontend
1. File: todo-frontend/public/index.html
Copy <! DOCTYPE html >
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title >Todo List</ title >
</ head >
< body >
< div id = "root" ></ div >
</ body >
</ html >
2. File: todo-frontend/src/index.js
Copy import React from 'react' ;
import ReactDOM from 'react-dom/client' ;
import App from './App' ;
const root = ReactDOM .createRoot ( document .getElementById ( 'root' ));
root .render (< App />);
3. File: todo-frontend/src/App.js
Copy import React from 'react' ;
import ProductList from './components/ProductList' ;
function App () {
return (
< div className = "App" >
< ProductList />
</ div >
);
}
export default App;
4. File: todo-frontend/src/components/ProductList.js
Copy import React , { useState , useEffect } from 'react' ;
import axios from 'axios' ;
const ProductList = () => {
const [ products , setProducts ] = useState ([]);
const [ name , setName ] = useState ( '' );
const [ price , setPrice ] = useState ( '' );
const [ stock , setStock ] = useState ( '' );
useEffect (() => {
fetchProducts ();
} , []);
const fetchProducts = async () => {
const response = await axios .get ( ` ${ process . env . REACT_APP_API_URL } /products` );
setProducts ( response .data);
};
const createProduct = async () => {
const newProduct = { name , price : parseFloat (price) , stock : parseInt (stock) };
await axios .post ( ` ${ process . env . REACT_APP_API_URL } /products` , newProduct);
fetchProducts ();
setName ( '' );
setPrice ( '' );
setStock ( '' );
};
const deleteProduct = async (id) => {
await axios .delete ( ` ${ process . env . REACT_APP_API_URL } /products/ ${ id } ` );
fetchProducts ();
};
return (
< div >
< h1 >Product List</ h1 >
< ul >
{ products .map (product => (
< li key = { product .id}>
{ product .name} - ${ product .price} - Stock: { product .stock}
< button onClick = {() => deleteProduct ( product .id)}>Delete</ button >
</ li >
))}
</ ul >
< div >
< h2 >Create Product</ h2 >
< input
type = "text"
placeholder = "Name"
value = {name}
onChange = {e => setName ( e . target .value)}
/>
< input
type = "text"
placeholder = "Price"
value = {price}
onChange = {e => setPrice ( e . target .value)}
/>
< input
type = "text"
placeholder = "Stock"
value = {stock}
onChange = {e => setStock ( e . target .value)}
/>
< button onClick = {createProduct}>Create</ button >
</ div >
</ div >
);
};
export default ProductList;
5. File: todo-frontend/package.json
Copy {
"name" : "todo-frontend" ,
"version" : "0.1.0" ,
"private" : true ,
"dependencies" : {
"@testing-library/jest-dom" : "^5.17.0" ,
"@testing-library/react" : "^13.4.0" ,
"@testing-library/user-event" : "^13.5.0" ,
"axios" : "^1.7.2" ,
"react" : "^18.3.1" ,
"react-dom" : "^18.3.1" ,
"react-scripts" : "5.0.1" ,
"web-vitals" : "^2.1.4"
} ,
"scripts" : {
"start" : "react-scripts start" ,
"build" : "react-scripts build" ,
"test" : "react-scripts test" ,
"eject" : "react-scripts eject"
} ,
"eslintConfig" : {
"extends" : [
"react-app" ,
"react-app/jest"
]
} ,
"browserslist" : {
"production" : [
">0.2%" ,
"not dead" ,
"not op_mini all"
] ,
"development" : [
"last 1 chrome version" ,
"last 1 firefox version" ,
"last 1 safari version"
]
}
}
6. File: todo-frontend/.env
Copy REACT_APP_API_URL=http://localhost:3000
todo-backend
1. File: todo-backend/main.go
Copy package main
import (
"todo-backend/database"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cors"
"gorm.io/gorm"
)
type Product struct {
ID uint `json:"id" gorm:"primaryKey"`
Name string `json:"name"`
Price float64 `json:"price"`
Stock int `json:"stock"`
}
var DB * gorm . DB
func main () {
database. Connect ()
DB = database.DB
DB. AutoMigrate ( & Product {})
app := fiber. New ()
app. Use (cors. New ( cors . Config {
AllowOrigins: "*" ,
AllowHeaders: "Origin, Content-Type, Accept" ,
}))
app. Get ( "/products" , GetProducts)
app. Post ( "/products" , CreateProduct)
app. Delete ( "/products/:id" , DeleteProduct)
app. Listen ( ":3000" )
}
func GetProducts (c * fiber . Ctx ) error {
var products [] Product
DB. Find ( & products)
return c. JSON (products)
}
func CreateProduct (c * fiber . Ctx ) error {
product := new ( Product )
if err := c. BodyParser (product); err != nil {
return c. Status ( 400 ). SendString (err. Error ())
}
DB. Create ( & product)
return c. JSON (product)
}
func DeleteProduct (c * fiber . Ctx ) error {
id := c. Params ( "id" )
var product Product
DB. First ( & product, id)
if product.ID == 0 {
return c. Status ( 404 ). SendString ( "No Product Found with ID" )
}
DB. Delete ( & product)
return c. SendString ( "Product Successfully deleted" )
}
2. File: todo-backend/database/connection.go
Copy package database
import (
"fmt"
"log"
"os"
"time"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
var DB * gorm . DB
func Connect () {
var err error
dsn := fmt. Sprintf ( "host= %s user= %s password= %s dbname= %s port= %s sslmode=disable" ,
os. Getenv ( "DB_HOST" ),
os. Getenv ( "DB_USER" ),
os. Getenv ( "DB_PASSWORD" ),
os. Getenv ( "DB_DATABASE" ),
os. Getenv ( "DB_PORT" ),
)
DB, err = gorm. Open (postgres. Open (dsn), & gorm . Config {
Logger: logger.Default. LogMode (logger.Info),
})
if err != nil {
log. Fatal ( "Failed to connect to database: " , err)
}
db, err := DB. DB ()
if err != nil {
log. Fatal ( "Failed to get database connection: " , err)
}
db. SetMaxIdleConns ( 10 )
db. SetMaxOpenConns ( 100 )
db. SetConnMaxLifetime (time.Hour)
}
3. File: todo-backend/go.mod
Copy module todo - backend
go 1.18
require (
github.com / gofiber / fiber / v2 v2. 52.4
gorm.io / driver / postgres v1. 5.7
gorm.io / gorm v1. 25.10
)
4. File: todo-backend/go.sum
(Secara otomatis dibuat oleh Go saat Anda menjalankan go mod tidy
atau menambahkan dependensi.)
Menjalankan Proyek
Backend
Pastikan PostgreSQL Berjalan :
Pastikan PostgreSQL berjalan dan dapat diakses dengan kredensial yang diberikan.
Anda bisa menggunakan Docker untuk menjalankan PostgreSQL:
Copy docker run --name postgres-db -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=root -e POSTGRES_DB=marketplace -p 5432:5432 -d postgres
Set Environment Variables :
Buat file .env
di root folder todo-backend
dan isi dengan:
Copy DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=root
DB_DATABASE=marketplace
end`, jalankan: sh go mod tidy go run main.go
Frontend
Install Dependencies :
Di folder todo-frontend
, jalankan:
Jalankan Frontend :
Masih di folder todo-frontend
, jalankan:
Frontend akan berjalan di http://localhost:3000
dan akan berkomunikasi dengan backend yang juga berjalan di port 3000.
Dengan mengikuti langkah-langkah di atas, Anda akan memiliki aplikasi todo-list sederhana yang dapat melakukan operasi read, create, dan delete menggunakan React untuk frontend dan Go dengan Fiber untuk backend.
Last updated 6 months ago