Project: GoFr (Orchestration & Management / Remote Procedure Call)
File: page.md

Just like Redis gofr also supports connection to SQL(mysql and postgres) databases based on configuration variables. Users can run MySQL and create a database locally using the following docker command: ```bash docker run --name gofr-mysql -e MYSQLROOTPASSWORD=root123 -e MYSQLDATABASE=testdb -p 3306:3306 -d mysql:8.0.30 ``` Access `test_db` database and create table customer with columns `id` and `name` ```bash docker exec -it gofr-mysql mysql -uroot -proot123 testdb -e "CREATE TABLE customers (id INT AUTOINCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL);" ``` Now the database with table is ready, we can connect our GoFr server to MySQL After adding MySQL configs `.env` will be updated to the following. ```dotenv APP_NAME=test-service HTTP_PORT=9000 REDIS_HOST=localhost REDIS_PORT=6379 DB_HOST=localhost DB_USER=root DB_PASSWORD=root123 DBNAME=testdb DB_PORT=3306 DB_DIALECT=mysql ``` Now in the following example, we'll store customer data using POST `/customer` and then use GET `/customer` to retrieve the same. We will be storing the customer data with `id` and `name`. After adding code to add and retrieve data from MySQL datastore, `main.go` will be updated to the following. ```go package main import ( "errors" "github.com/redis/go-redis/v9" "gofr.dev/pkg/gofr" ) type Customer struct { ID int `json:"id"` Name string `json:"name"` } func main() { // initialise gofr object app := gofr.New() app.GET("/redis", func(ctx *gofr.Context) (interface{}, error) { // Get the value using the Redis instance val, err := ctx.Redis.Get(ctx.Context, "test").Result() if err != nil && !errors.Is(err, redis.Nil) { // If the key is not found, we are not considering this an error and returning "" return nil, err } return val, nil }) app.POST("/customer/{name}", func(ctx *gofr.Context) (interface{}, error) { name := ctx.PathParam("name") // Inserting a customer row in database using SQL _, err := ctx.SQL.ExecContext(ctx, "INSERT INTO customers (name) VALUES (?)", name) return nil, err }) app.GET("/customer", func(ctx *gofr.Context) (interface{}, error) { var customers []Customer // Getting the customer from the database using SQL rows, err := ctx.SQL.QueryContext(ctx, "SELECT * FROM customers") if err != nil { return nil, err } for rows.Next() { var customer Customer if err := rows.Scan(&customer.ID, &customer.Name); err != nil { return nil, err } customers = append(customers, customer) } // return the customer return customers, nil }) app.Run() } ``` To update the database with the customer data access use through this curl command through terminal ```bash curl --location --request POST 'http://localhost:9000/customer/abc' curl --location --request POST 'http://localhost:9000/customer/xyz' ``` Now when we access {% new-tab-link title="http://localhost:9000/customer" href="http://localhost:9000/customer" /%} we should see the following output ```json { "data": [ { "id": 1, "name": "abc" }, { "id": 2, "name": "xyz" } ] } ``` names. For example, `IsEmployed` field in the struct matches `is_employed` column in the database, `Age` field matches `age` column, etc. Primary Key: The first field of the struct is typically used as the primary key for data operations. However, user can customize this behavior using GoFr's features.