by Abu Zubayr

Redis dan Implementasinya di Golang

Bismillah...

Redis merupakan sebuah sistem basis data berbasis key-value store. Jika anda belum mengetahui apa itu key-value store maka akan saya jelaskan sedikit mengenai hal tersebut. Key-value adalah non-relational database yang menyimpan data dengan metode penyimpanan key-value. Jadi data yang disimpan adalah berupa key sebagai unique identifier terhadap sebuah value. Hal ini tentu berbeda dengan database pada umumnya yang kita jumpai seperti di MySQL dimana data yang disimpan berupa tabel-tabel.

Untuk lokasi penyimpanan data, redis juga berbeda dengan database lain pada umumnya. Dimana penyimpanan data redis dilakukan di memory bukan di hard drive. Kemudian dari segi penggunaanya, redis digunakan untuk menyimpan data yang sifatnya non permanen, oleh sebab itu jika sebuah server mati maka seluruh data tadi akan ikut hilang.

Salah satu contoh implementasi penggunaan redis adalah untuk penyimpanan data session di sebuah website. Dimana biasanya secara default data session tersebut tersimpan dalam sebuah flat file. Jika dibandingkan dari segi kecepatan akses data, maka redis jauh lebih cepat jika dibandingkan dengan session yang disimpan di flat file biasa. Hal ini dikarenakan redis mengakses datanya langsung ke memory sebuah pc/komputer yang tentu akan jauh lebih cepat.

Hingga kini redis bisa digunakan dihampir seluruh bahasa pemgrograman populer seperti Java, PHP, Node JS, Golang, Python, C, dan bahasa lainnya yang bisa anda lihat di https://redis.io/clients. Pada tutorial ini saya akan coba mengimplementasikan redis ini dibahasa pemrograman Golang. Di go sendiri terdapat banyak module yang bisa anda gunakan, akan tetapi pada tutorial ini saya akan menggunakan module go-redis/redis. Oke, tanpa berlama-lama langsung saja berikut adalah langkah-langkah penggunaan redis di golang :
  1. Buat sebuah project golang misalnya dengan nama project “redis-golang”
  2. Buka terminal dan lakukan Inisialisasi project baru tersebut dengan perintah go mod init redis-golang
  3. Tambahkan module redis digolang dengan perintah go get github.com/go-redis/redis/v8
  4. Buat sebuah file misalnya dengan nama server.js
  5. Di file server.js yang pertama yang perlu dilakukan adalah membuat koneksi. Caranya adalah seperti dibawah ini.
  6. con := redis.NewClient(&redis.Options{
      Addr: "localhost:6379",
      Password: "",
    })
    Pada source code diatas terlihat kita membuat sebuah koneksi ke redis dengan host/address dari redis sendiri di “localhost” yang berjalan di port “6379”. Sesuaikan dengan settingan redis di pc/laptop anda, kemudian jika menggunakan password, maka masukkan sekaligus di parameter Password tersebut.
  7. Setelah selesai membuat koneksi diatas, selanjutnya adalah mencoba membuat perintah yang biasa digunakan di redis seperti set, get dan delete. Sebelum memasukkan perintah tersebut, buat sebuah context terlebih dahulu seperti dibawah ini :
  8. ctx := context.Background()
    • Set
    • Perintah `set` adalah perintah yang digunakan untuk menambah atau melakukan perubahan data berdasarkan key tertentu. Untuk memasukkan perintah tersebut caranya adalah sebagai berikut :
      err := con.Set(ctx, "token", "101", 0).Err()
      if err != nil {
         panic(err)
      }
      Pada code diatas, method Set menerima parameter berupa (context, key, value dan exipiration). Berdasarkan data yang dimasukkan diatas, maka data yang dimasukkan memiliki key dengan nama token dan berisi value 101. Kemudian untuk expiration-nya kita set dengan 0 artinya data tersebut tidak memiliki masa expired alias akan terus ada di memory redis selama server tidak mati atau data tersebut tidak dihapus.
    • Get
    • Perintah `get` sendiri digunakan untuk melakukan pengambilan data yang sebelumnya sudah dimasukkan ke redis. Untuk melakukan perintah tersebut di golang caranya adalah sebagai berikut :
      val, err := con.Get(ctx, "token").Result()
      if err != nil {
        panic(err)
      }
      
      fmt.Println(val)
      Pada code diatas, method Get memiliki parameter (context dan key) dimana parameter key adalah merupakan key dari data yang sebelumnya sudah kita masukkan kedalam redis. Ketika data dengan key tersebut ada, maka variable val akan terisi data dari key tersebut. Namun jika data dengan key tadi tidak ada maka variable err akan berisi pesan error bahwa data dengan key tersebut tidak ada di server redis.
    • Delete
    • Selanjutnya di redis juga terdapat perintah `delete` dimana perintah ini digunakan untuk menghapus data yang ada di server redis. Untuk melakukan perintah ini di golang caranya adalah sebagai berikut :
      err = con.Del(ctx, "token").Err()
      if err != nil {
         panic(err)
      }
      Sama seperti method get tadi, method `delete` ini juga memiliki parameter berupa (context dan key). Jika data yang di hapus tersebut ada di database, maka data akan terhapus melalui method tersebut, akan tetapi jika data tersebut tidak ada maka kita tampung error tersebut kedalam variable err.
    • Increment & Decrement
    • Sebagai tambahan, redis juga bisa melakukan proses increment dan decrement yang umumnya sering kita jumpai di bahasa pemrograman. Caranya adalah sebagai berikut :
      Increment
      err = con.Incr(ctx, "angka").Err()
      if err != nil {
         panic(err)
      }
      
      Code diatas, method increment menerima parameter berupa (context dan key), namun disini perlu diperhatikan bahwa data yang akan dilakukan increment harus berupa angka. Method `Incr` ini juga melakukan increment dengan step 1, untuk melakukan increment dengan step yang sesuai dengan keinginan anda, maka bisa menggunakan method `IncrBy` seperti dibawah ini :
      err = con.IncrBy(ctx, "angka", 10).Err()
      if err != nil {
         panic(err)
      }
      Terlihat di code diatas, method `IncrBy` menerima parameter berupa (context, key, dan step increment-nya). Pada contoh diatas, saya memasukkan step-nya 10. Jadi data dengan key angka akan bertambah sebanyak 10.
      Decrement
      err = con.Decr(ctx, "angka").Err()
      if err != nil {
        panic(err)
      }
      Method `Decr` diatas menerima parameter (context dan key) dengan menggunakan method ini, proses decrement akan dilakukan dengan step 1 setiap method tersebut dipanggil atau digunakan. Untuk melakukan decrement dengan nilai custom step, caranya adalah seperti dibawah ini dengan menggunakan method `DecrBy` :
      err = con.DecrBy(ctx, "angka", 4).Err()
      if err != nil {
         panic(err)
      }
      Pada method diatas memiliki parameter (context, key dan step decrement-nya). Pada method diatas decrement dilakukan dengan 4 step.
Untuk source code lengkapnya seperti dibawah ini :
package main

import (
	"context"
	"fmt"

	"github.com/go-redis/redis/v8"
)

func main() {
	con := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
	})

	ctx := context.Background()
	err := con.Set(ctx, "token", "101", 0).Err()
	if err != nil {
		panic(err)
	}

	val, err := con.Get(ctx, "token").Result()
	if err != nil {
		panic(err)
	}
	fmt.Println(val)

	err = con.Del(ctx, "token").Err()
	if err != nil {
		panic(err)
	}

	val, err = con.Get(ctx, "token").Result()
	if err != nil {
		fmt.Println("Data kosong")
	}

	fmt.Println("Data dengan key token setelah dihapus ", val)

	fmt.Println("\nTes set angka/numeric di redis")
	err = con.Set(ctx, "angka", 0, 0).Err()
	if err != nil {
		panic(err)
	}

	val, err = con.Get(ctx, "angka").Result()
	if err != nil {
		fmt.Println("Data dengan key angka kosong")
	} else {
		fmt.Println("Angka sebelum increment ", val)
	}

	err = con.Incr(ctx, "angka").Err()
	if err != nil {
		panic(err)
	}

	val, err = con.Get(ctx, "angka").Result()
	if err != nil {
		fmt.Println("Data dengan key angka kosong")
	} else {
		fmt.Println("Angka setelah increment ", val)
	}

	err = con.IncrBy(ctx, "angka", 10).Err()
	if err != nil {
		panic(err)
	}

	val, err = con.Get(ctx, "angka").Result()
	if err != nil {
		fmt.Println("Data dengan key angka kosong")
	} else {
		fmt.Println("Angka setelah increment 10 = ", val)
	}

	err = con.Decr(ctx, "angka").Err()
	if err != nil {
		panic(err)
	}

	val, err = con.Get(ctx, "angka").Result()
	if err != nil {
		fmt.Println("Data dengan key angka kosong")
	} else {
		fmt.Println("Angka setelah decrement = ", val)
	}

	err = con.DecrBy(ctx, "angka", 4).Err()
	if err != nil {
		panic(err)
	}

	val, err = con.Get(ctx, "angka").Result()
	if err != nil {
		fmt.Println("Data dengan key angka kosong")
	} else {
		fmt.Println("Angka setelah decrement 4 = ", val)
	}
}

Demikian postingan saya mengenai Redis dan Implementasinya di Golang, Jika ada pertanyaan silahkan ditanyakan dikolom komentar dibawah. Source code dari project ini sendiri bisa diakses melalui github di https://github.com/sardiabuzubayr/redis-golang

Demikian, semoga bermanfaat wassalamualaikum warahmatullah wabarakaatuh.
Share:

Memasang Vue Router di Laravel

Memasang Vue Router di Laravel

Bismillah

Melanjutkan postingan sebelumnya mengenai Setup Vue Js di Laravel dalam Satu Project. Dipostingan tersebut kita telah berhasil melakukan konfigurasi awal vue agar bisa bundling dengan project laravel. Nah selanjutnya adalah kita akan menerapkan vue router di project tersebut. Vue router adalah merupakan library dari vue yang khususnya untuk melakukan routing agar aplikasi bisa berjalan layaknya Single Page Application pada umumnya.

Untuk menambahkan router di vue, masukkan perintah di terminal atau command prompt anda dengan perintah :
npm install vue-router
Tunggu hingga proses selesai.

Untuk mempermudah penerapan penggunaan vue router tersebut, kita akan membuat dua buah page/halaman. Halaman pertama adalah halaman dashboard, dan yang satunya lagi adalah halaman profile. Berikut adalah langkah-langkahnya :
  1. Buat dua buah file dengan nama Dashboard.vue dan Profile.vue di direktori `resources\js\componenents`.
  2. Pada masing-masing halaman tersebut buat template vue sederhana. Sebagai contoh :
  3. Dashboard.vue
    <template>
        <h3>Hai, Ini adalah halaman dashboard</h3>
    </template>
    
    <script>
        export default {
            name:'dashboard'
        }
    </script>

    Profile.vue
    <template>
        <h3>Hai ini adalah halaman profile</h3>
    </template>
    
    <script>
        export default {
            name:'profile'
        }
    </script>
  4. Kemudian setelah membuat kedua file diatas, buat lagi sebuah file dengan nama Navigation.vue. Di file inilah link/routing akan ditampilkan. Berikut adalah isi dari file Navigation.vue :
  5. <template>
        <div>
            <router-link to="/dashboard">Dashboard</router-link> | 
            <router-link to="/profile">Profile</router-link>
        </div>
    </template>
    
    <script>
        export default{
            name:'navigation'
        }
    </script>
    Seperti terlihat diatas, ada component bernama router-link. Dimana di component inilah kita meletakkan link dari page yang sebelumnya yang sudah dibuat menggunakan props to.
  6. Edit file App.vue menjadi seperti berikut :
  7. <template>
        <div class='container'>
            <Navigation />
            <router-view ></router-view>
        </div>
    </template>
    
    <script>
    import Navigation from './Navigation.vue'
    
    export default {
        components : {Navigation}
    }
    </script>
  8. Kemudian edit kembali file app.js, menjadi seperti dibawah ini :
  9. import App from './components/App'
    import { createApp } from 'vue'
    import { createRouter, createWebHistory } from 'vue-router'
    import Dashboard from './components/Dashboard.vue'
    import Profile from './components/Profile.vue'
    
    const router = createRouter({
      history: createWebHistory(),
      routes: [
        {
          path: '/dashboard',
          component: Dashboard,
          name: 'dashboard',
          meta: {
              title: 'Dashboard'
          },
        },
        {
          path: '/profile',
          component: Profile,
          name: 'profile',
          meta: {
              title: 'Profile'
          },
        },
      ],
    });
    
    const app = createApp({
        components: {
            App
          }
    });
    
    app.use(router)
    app.mount('#app');
    Penjelasan :
    • Yang diperlukan untuk membuat router adalah dengan meng-import beberapa method dari vue-router yaitu createRouter dan createWebHistory.
    • Didalam method createRouter, tambahkan parameter history dan routes.
    • Pada parameter history isinya adalah createWebHistory yang mana parameter history ini gunanya adalah agar history dari url dibrowser yang dibuat bisa dibaca oleh vue-router dan di render sebagai SPA.
    • Dibagian parameter routes, disini kita daftarkan seluruh routes yang diperlukan. Sebagai contoh, disini kita memerlukan routing untuk halaman Dashboard dan Profile. Yang perlu diperhatikan pada saat membuat routes adalah di parameter path, component, dan name. Dimana parameter path berisi url path yang merujuk ke component tertentu. Kemudian component merupakan komponen apa yang akan ditampilkan/dirender pada saat berada di path tadi, dan name adalah merupakan nama routes itu sendiri.
  10. Sampai disini routing di vue sudah selesai dibuat. Dan pada saat dijalankan maka tampilannya adalah seperti dibawah ini :
  11. Simple vue router laravel
    Saat di klik salah satu link/url maka akan membuka page tersebut tanpa harus mereload keseluruhan halaman seperti dibawah ini :
    Simple vue router laravel
  12. Terakhir agar tidak muncul pesan Not Found dilaravel pada saat mereload page penuh, maka perlu diubah routing laravel di `routes\web.php` menjadi seperti berikut :
  13. <?php
    
    use Illuminate\Support\Facades\Route;
    
    /*
    |--------------------------------------------------------------------------
    | Web Routes
    |--------------------------------------------------------------------------
    |
    | Here is where you can register web routes for your application. These
    | routes are loaded by the RouteServiceProvider within a group which
    | contains the "web" middleware group. Now create something great!
    |
    */
    
    Route::get('/{any}', function () {
        return view('welcome');
    })->where('any','.*');

Demikian tutorial lanjutan mengenai Memasang Vue Router di Laravel, Jika ada tidak dipahami silahkan bertanya dikolom komentar dibawah atau bisa melalui email private.sardi@gmail[dot]com. Untuk Source code dari project ini sendiri bisa diakses melalui github di https://github.com/sardiabuzubayr/sample-vue-laravel

Semoga bermanfaat wassalamualaikum warahmatullah wabarakaatuh.

Share:

Belajar GraphQL, Serta Contoh Implementasinya di Golang

https://celiksoftware.blogspot.com/2022/01/belajar-graphql-serta-contoh.html


Bismillah

Saat membuat sebuah API, terkadang tidak hanya satu jenis platform yang meng-consume api tersebut. Di era sekarang ini, saat men-develop sebuah aplikasi berbasis website, maka juga akan diiringi dengan aplikasi mobile-nya baik Android maupun IOS. Jika jenis dan jumlah data yang dikirim oleh backend disamakan antara platform website dan mobile tadi, maka akan menjadi kurang efektif karena belum tentu data yang dibutuhkan oleh aplikasi website sama dengan data yang dibutuhkan oleh mobile, baik dari jenis dan jumlah datanya. Mungkin saja di website membutuhkan data dengan 5 atau seluruh field akan ditampilkan, tetapi di mobile mungkin hanya beberapa field saja dan jumlah barisnya pun terbatas.

Untuk menangani jenis permintaan yang berbeda tersebut, biasanya seorang backend developer membuat dua buah api yang berbeda, dimana satu api untuk di consume oleh website, sedangkan satunya lagi untuk mobile. Tidak ada yang salah dengan cara seperti ini, hanya saja jika aplikasi yang dibuat sudah sangat besar akan tetapi jumlah backend developer yang sedikit, maka imbasnya adalah aplikasi yang dibuat semakin lama untuk dirilis ke client karena harus membuat api tersendiri untuk masing-masing platform. Nah, jika hal semacam ini terjadi maka solusinya adalah dengan menggunakan GraphQL. Apa itu GraphQL? Kita bahas lebih detail.

GraphQL adalah bahasa query (query language) untuk sebuah API yang dibuat oleh Facebook. Bahasa query yang dimaksudkan disini bukanlah seperti query database yang sering anda jumpai di SQL maupun NoSQL. Query yang dimaksudkan disini adalah data dari API server backend, bisa dilakukan filterisasi langsung oleh client (web browser ataupun mobile) sesuai yang diinginkan oleh client melalui sebuah query yang dikirimkan ke server. Inilah yang merupakan kelebihan dari GraphQL jika dibandingkan dengan REST yang sering kita gunakan.

Supaya lebih mantap pemahaman mengenai GraphQL ini, maka kita akan langsung praktekkan bagaimana pengkodeannya di sisi backend. Disini saya akan mencontohkan membuat GraphQL server menggunakan bahasa golang dengan echo framework sebagai webserver dan gorm sebagai library database.

Membuat Database

Pertama kita buat sebuah database baru `nama terserah anda` kemudian buat tabel dengan script sql dibawah ini :
CREATE TABLE `level_user` (
 `id_level` int(2) NOT NULL AUTO_INCREMENT,
 `nama` varchar(100) NOT NULL,
 PRIMARY KEY (`id_level`)
);

CREATE TABLE `users` (
 `email` varchar(100) NOT NULL,
 `nama` varchar(50) NOT NULL,
 `no_handphone` varchar(15) DEFAULT NULL,
 `alamat` text DEFAULT NULL,
 `ktp` varchar(255) DEFAULT NULL,
 `id_level` int(2) NOT NULL,
 PRIMARY KEY (`email`) USING BTREE
);

INSERT INTO `level_user` (`id_level`, `nama`) VALUES
	(1, 'Super Admin'),
	(2, 'Admin');

INSERT INTO `users` (`email`, `nama`, `no_handphone`, `alamat`, `ktp`, `id_level`) VALUES
	(fulan@gmail.com', 'Ahmad Zainuddin', '0853xxxxx', 'Jalan Kemana', '', 1),
	('siapa@gmail.com', Zubayr, '08xxxx', 'Jalan - ', 'ktp.jpg', 2),
	(saya@gmail.com', Zakaria, '08xxxx', 'Jalan - ', 'ktp.jpg', 2);


Setup Project Baru Golang

Buat sebuah project baru di golang dan jalankan perintah berikut di terminal : go mod init mygraphql Setelah itu tambahkan modul dibawah ini :
go get github.com/labstack/echo/v4
go get gorm.io/gorm
go get gorm.io/driver/mysql
go get github.com/graphql-go/graphql 
go get github.com/graphql-go/handler
Didalam project yang sudah dibuat tadi, buat beberapa direktori baru dengan nama seperti dibawah ini :
setup project golang

Konfigurasi Database

Setelah selesai membuat project golang. Kemudian kita buat konfigurasi database didalam direktori config, buat sebuah file dengan nama database.go. Kemudian isi dengan code dibawah ini :
package config

import (
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)

var DB *gorm.DB

func ConnectDB() {
    host := "localhost"
    port := "3306"
    dbname := "blogspot"
    username := "root"
    password := ""

    dsn := username + ":" + password + "@tcp(" + host + ":" + port + ")/" + dbname + "?charset=utf8&parseTime=true&loc=Local"
    var err error
    DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{SkipDefaultTransaction: true})
    if err != nil {
        panic("Cannot connect database")
    }
    DB.AutoMigrate()
}
Sesuaikan konfigurasi diatas dengan server MySQL yang berjalan di komputer anda.

Membuat Model

Di direktori model yang sudah dibuat tadi, buat 2 buah file baru yaitu `level.go` dan `users.go`. Isi masing-masing file dengan code dibawah ini :
level.go
package model

import (
    "mygraphql/config"

    "gorm.io/gorm"
)

type LevelUser struct {
    IdLevel int    `json:"id_level"`
    Nama    string `json:"nama"`
}

func (LevelUser) TableName() string {
    return "level_user"
}

func GetLevel(idLevel int) ([]LevelUser, error) {
    levels := new([]LevelUser)
    var result *gorm.DB
    if idLevel != 0 {
        result = config.DB.Where("id_level = ? ", idLevel).Find(levels)
    } else {
        result = config.DB.Find(levels)
    }
    return *levels, result.Error
}

users.go
package model

import "mygraphql/config"

type Users struct {
    Email       string `json:"email" form:"email" gorm:"primaryKey"`
    Nama        string `json:"nama" form:"nama"`
    NoHandphone string `json:"no_handphone" form:"no_handphone"`
    Alamat      string `json:"alamat" form:"alamat"`
    Ktp         string `json:"ktp" form:"ktp"`
}

func GetUsers(keywords string) ([]Users, error) {
    var users []Users
    result := config.DB.Where("email LIKE ? OR nama LIKE ?", "%"+keywords+"%", "%"+keywords+"%").Find(&users)

    return users, result.Error
}

Kedua file diatas kita gunakan untuk mendefinisikan fungsi yang akan mengambil data dari database yang sudah kita buat sebelumnya. Untuk penjelasan mengenai ini lebih jelasnya bisa anda baca dipostingan saya mengenai Crud API di Golang Menggunakan Echo Framework dan GORM.

Setup GraphQL

Nah, sekarang kita masuk ke bagian inti dari postingan ini, yaitu berkaitan dengan graphql itu tadi. Di direktori `graphql` buat dua buah file baru yaitu `query.go` dan `handler.go`.
query.go
package graphql

import (
    "mygraphql/model"

    "github.com/graphql-go/graphql"
)

var (
    level = graphql.NewObject(
        graphql.ObjectConfig{
            Name: "Level",
            Fields: graphql.Fields{
                "id_level": &graphql.Field{Type: graphql.ID},
                "nama":     &graphql.Field{Type: graphql.String},
            },
            Description: "Data level",
        },
    )
    user = graphql.NewObject(
        graphql.ObjectConfig{
            Name: "User",
            Fields: graphql.Fields{
                "email":        &graphql.Field{Type: graphql.ID},
                "nama":         &graphql.Field{Type: graphql.String},
                "no_handphone": &graphql.Field{Type: graphql.String},
                "alamat":       &graphql.Field{Type: graphql.String},
                "ktp":          &graphql.Field{Type: graphql.String},
            },
            Description: "Data users",
        },
    )
)

func levelData() *graphql.Field {
    return &graphql.Field{
        Type: graphql.NewList(level),
        Resolve: func(p graphql.ResolveParams) (interface{}, error) {
            idLevel, _ := p.Args["id_level"].(int)
            listLevel, err := model.GetLevel(idLevel)
            return listLevel, err
        },
        Description: "List Level",
        Args: graphql.FieldConfigArgument{
            "id_level": &graphql.ArgumentConfig{Type: graphql.Int},
        },
    }
}

func usersData() *graphql.Field {
    return &graphql.Field{
        Type: graphql.NewList(user),
        Resolve: func(p graphql.ResolveParams) (interface{}, error) {
            keywords, _ := p.Args["keywords"].(string)
            listUser, err := model.GetUsers(keywords)
            return listUser, err
        },
        Description: "List User",
        Args: graphql.FieldConfigArgument{
            "keywords": &graphql.ArgumentConfig{Type: graphql.String},
        },
    }
}

func newQuery() *graphql.Object {
    return graphql.NewObject(graphql.ObjectConfig{
        Name: "Query",
        Fields: graphql.Fields{
            "users": usersData(),
            "level": levelData(),
        },
    })
}

Penjelasan :
  • Di file ini pertama kita deklarasikan terlebih dahulu variabel level dan user. Dimana di variabel tersebut diisi dengan fungsi NewObject dari graphql. Di variabel ini kita juga mendefinisikan field apa saja yang tersedia.
  • Beralih ke fungsi levelData dan usersData dimana fungsi ini memiliki return type berupa struct *graphql.Field.
  • Type: graphql.NewList(ofType graphql.Type) kita masukkan variabel `level` ataupun `users` yang sudah dibuat sebelumnya.
    Resolve: func(p graphql.ResolveParams) (interface{}, error) {}. Berisi data dari database tadi yang akan kita kembalikan ke client. Sebenarnya data yang di return disini bebas tidak hanya terbatas dari database saja, melainkan dari sumber lainnya pun boleh dilakukan.
    Args: graphql.FieldConfigArgument{}. Jika data membutuhkan filter di client, maka kita bisa mendifinisikannya dibagian ini.
  • Terakhir pada fungsi newQuery dimana pada fungsi ini kita jabarkan query yang bisa di panggil oleh client nantinya. Seperti yang terlihat di source code, kita mendaftarkan dua buah field data yang bisa di panggil oleh client. Yang pertama users dan yang kedua adalah level. Jadi dengan menggunakan field tersebutlah kita akan melakukan query data di client.

handler.go
package graphql

import (
    "github.com/graphql-go/graphql"
    "github.com/graphql-go/handler"
    "gorm.io/gorm"
)

func NewHandler() (*handler.Handler, error) {
    schema, err := graphql.NewSchema(
        graphql.SchemaConfig{
            Query: newQuery(),
        },
    )

    if err != nil {
        return nil, err
    }

    return handler.New(&handler.Config{
        Schema:   &schema,
        Pretty:   true,
        GraphiQL: true,
    }), nil
}

Penjelasan :
  • Dibagian handler kita buat sebuah fungsi NewHandler, dimana fungsi ini nantinya akan terhubung ke web server atau router dari echo. Terlihat dari baris selanjutnya kita definisikan schema yang sudah dibuat tadi dimana isinya adalah fungsi newQuery yang sudah dibuat sebelumnya di file `query.go` tadi.
  • Setelah selesai membuat file handler.go, selanjutnya yang terakhir adalah mendaftarkan handler tersebut ke router echo yang akan kita buat di file `server.go`. Isi dari file server.go adalah seperti dibawah ini :

server.go
package main

import (
    "fmt"
    "mygraphql/config"
    "mygraphql/graphql"

    "github.com/labstack/echo/v4"
)

func main() {
    config.ConnectDB()
    route := echo.New()

    h, err := graphql.NewHandler()
    if err != nil {
        fmt.Println(err)
    }
    route.POST("/graphql", echo.WrapHandler(h))
    route.Start(":9000")
}

type Response struct {
    ErrorCode int         `json:"error_code" form:"error_code"`
    Message   string      `json:"message" form:"message"`
    Data      interface{} `json:"data"`
}

Jika anda mengikuti postingan saya mengenai Rest API di Golang Menggunakan Echo Framework, disana sebagian besar sudah saya jelaskan mengenai penggunaan echo sebagai web server. Pada postingan ini yang perlu anda perhatikan hanya pada bagian :
h, err := graphql.NewHandler()
if err != nil {
    fmt.Println(err)
}
route.POST("/graphql", echo.WrapHandler(h))

Di bagian ini kita melakukan pemanggilan fungsi NewHandler yang sebelumnya sudah dibuat pada file `handler.go`. Kemudian pada baris akhir kita buat sebuah route dimana route tersebut adalah method post dengan url /graphql.

Setelah selesai, terakhir kita akan melakukan uji coba terhadap api graphql yang sudah dibuat. Disini saya menggunakan postman, atau anda boleh menggunakan tools lain yang biasa anda gunakan. Berikut adalah hasil pengujiannya :

  1. Pengujian dengan memanggil seluruh field yang tersedia di api graphql
  2. Pengujian dengan memanggil seluruh field yang tersedia di api graphql
  3. Pengujian dengan menggunakan memasukkan field yang spesifik
  4. Pengujian dengan menggunakan memasukkan field yang spesifik
  5. Pengujian dengan menggunakan filter dan field yang spesifik
  6. Pengujian dengan menggunakan filter dan field yang spesifik

Catatan :
Yang perlu anda perhatikan pada saat melakukan request data ke api graphql adalah query yang dikirim. Di postman sendiri sudah terdapat fitur graphql yang bisa anda gunakan. Output dari fitur graphql postman sendiri jika dilihat dalam bentuk curl contohnya adalah seperti dibawah ini :
curl --location --request POST 'http://localhost:9000/graphql' \
--header 'Content-Type: application/json' \
--data-raw '{"query":"query{\r\n    users (keywords:\"Ahmad\") {\r\n        email\r\n        nama\r\n        no_handphone\r\n    }\r\n    level (id_level:1){\r\n        id_level\r\n        nama\r\n    }\r\n}","variables":{}}'

Demikian postingan saya mengenai Belajar GraphQL, Serta Contoh Implementasinya di Golang, Jika ada pertanyaan silahkan ditanyakan dikolom komentar dibawah. Source code dari project ini sendiri bisa diakses melalui github di https://github.com/sardiabuzubayr/graphql-golang.

Demikian, semoga bermanfaat wassalamualaikum warahmatullah wabarakaatuh.
Share:

Setup Vue Js di Laravel dalam Satu Project

Langkah-Langkah Setup Vue Js di Laravel dalam 1 Project
Bismillah

Sebagai seorang fullstack developer, terkadang kita merasa kurang nyaman ketika develop sebuah aplikasi yang memiliki dua buah project yang berbeda. Dimana satu project sebagai backend dan satu-nya lagi sebagai frontend.

Sebelum munculnya berbagai framework dan library untuk frontend seperti vue, react, angular dll, biasanya seorang fullstack developer hanya bekerja disatu project saja. Biasanya untuk urusan tampilan, framework yang memakai konsep MVC (Model View Controller) maka letaknya adalah di bagian direktori view. Sebagai contoh, untuk laravel sendiri yang memakai konsep MVC, maka pengaturan tampilan berada di bagian resources/views secara default. Namun setelah kemunculan framework ataupun library frontend tadi, maka untuk frontend biasanya memiliki project tersendiri yang sudah bundling didalamnya node modules.

Dari permasalahan diatas agar proses develop menjadi mudah untuk seorang fullstack, maka solusinya adalah menyatukan backend dan frontend didalam sebuah project. Untuk laravel sendiri, ada sebuah node modules yang berfungsi untuk menyatukan Vue js ataupun library lainnya kedalam project laravel yakni laravel-mix. Mungkin di framework php lain seperti Codeigniter, Yii dan yang lainnya juga memiliki cara tersendiri untuk melakukan hal tersebut.

Baiklah, sebelum melakukan melakukan setup penggabungan library Vue dengan Laravel. Beberapa tools yang harus terinstal di laptop atau pc anda adalah node js dan composer. Jika belum terinstal, maka lakukan proses penginstalan keduanya terlebih dahulu.

Disini saya akan mencontohkan setup mulai dari awal yang dimulai dari pembuatan project laravel terlebih dahulu. Langkah-langkahnya adalah seperti berikut ini :
  • Buka terminal/command line, kemudian buat sebuah project laravel baru dengan cara memasukkan perintah berikut :
  • composer create-project laravel/laravel nama-project-anda
    Disini saya menggunakan composer untuk membuat project laravel. Selain menggunakan composer ada cara lain yang bisa anda lihat langsung di website resminya di https://laravel.com/docs/8.x/installation.
  • Setelah selesai, buka editor favorit anda kemudian tambahkan project yang sudah anda buat tadi kedalam editor tersebut.
  • Edit file package.json dibagian devDependencies, ubah menjadi seperti dibawah ini :
  •    "devDependencies": {
            "laravel-mix": "^6.0.6",
            "axios": "^0.21",
            "lodash": "^4.17.19",
            "postcss": "^8.1.14",
            "vue": "^3.2.26",
            "vue-loader": "^16.8.3",
            "vue-template-compiler": "^2.6.14",
            "vue-router": "^4.0.12"
        }
    Dibagian ini kita memasukkan modules yang dibutuhkan yakni vue, vue-loader, vue-template-compiler dan vue-router.
  • Setelah selesai, di terminal/command line masukkan perintah :
  • npm install
  • Kemudian masukkan lagi perintah dibawah ini :
  • npm run watch
    Perintah diatas gunanya adalah untuk melakukan compile script vue secara otomatis jika ada perubahan pada source code vue yang kita buat. Pastikan proses ini berhasil dan tidak terjadi error.
  • Selanjutnya jika sudah berhasil, buat sebuah direktori baru dengan nama `components` didirektori `resources/js`. Didalam direktori `components` tadi buat sebuah file dengan nama `App.vue`. Selanjutnya isi file tersebut dengan source code sederhana seperti dibawah ini :
  • <template>
        <div class='container'>
            <h1>Selamat Datang</h1>
        </div>
    </template>
  • Setelah itu edit file wellcome.blade.php yang berada didirektori resources/views/wellcome.blade.php sehingga menjadi seperti dibawah ini :
  • <html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
        <head>
            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <title>Laravel | Vue js</title>
            <link href="{{ mix('/css/app.css') }}" rel="stylesheet"/>
        </head>
        <body>
            <div id="app">
                <App/>
            </div>
            <script src="{{ mix('js/app.js') }}"></script>
        </body>
    </html>
  • Kembali ke terminal anda, jalankan server local laravel dengan perintah :
  • php artisan serve
  • Buka browser, kemudian masuk ke url local laravel tadi di http://localhost:8000. Jika berhasil, maka akan muncul halaman index-nya seperti gambar dibawah ini :
  • Localhost laravel with vue frontend
Sampai disini kita sudah berhasil menggabungkan laravel dengan vue js. Di tutorial selanjutnya insyaAllah kita akan membahas bagaimana supaya request dari browser client bisa dibaca oleh router vue js. Jika ada pertanyaan mengenai postingan Setup Vue Js di Laravel dalam Satu Project silahkan ditanyakan dikolom komentar. Source code dari project ini sendiri bisa diakses melalui github di https://github.com/sardiabuzubayr/sample-vue-laravel

Demikian, semoga bermanfaat wassalamualaikum warahmatullah wabarakaatuh.
Share:

Trigger Database, Fungsi dan Manfaatnya

Trigger Database, Fungsi dan Manfaatnya
Bismillah...

Pada kasus tertentu, terkadang kita menginginkan sebuah script sql tertentu di eksekusi ketika terjadi proses insert, update ataupun delete di database. Pada aplikasi kasir misalnya, saat kasir menginput barang yang dibeli oleh customer di mesin kasir dan proses transaksi tersebut berhasil dilakukan, maka stok barang yang dibeli tentu akan berkurang. Atau contoh lain seperti anda berbelanja disebuah online shop misalnya, barang atau item yang anda checkout akan otomatis berkurang stoknya di penjual. Nah, sekarang bagaimanakah menerapkan sistem tersebut? Jika terjadi proses seperti ini kita akan melakukan update stok di tabel barang atau item. Mungkin selama ini anda banyak melakukannya di dalam source code aplikasi secara langsung. Memang tidak mengapa melakukan hal seperti itu didalam source code langsung, akan tetapi ada cara yang lebih baik dan efisien yang bisa anda terapkan yakni dengan menggunakan trigger database.

Apa itu trigger, apa fungsi dan manfaatnya ? Trigger adalah kumpulan script sql yang dieksekusi secara otomatis ketika terjadi proses DML (Data Manipulation Language) seperti insert, update dan delete di pada sebuah tabel. Umumnya trigger memiliki opsi apakah script sql akan di eksekusi sebelum atau sesudah, atau kedua-duanya.

Fungsi Trigger :
  • Mengeksekusi script sql secara otomatis ketika terjadi perubahan pada sebuah tabel.
  • Menjaga integritas data.
  • Mencegah proses perubahan yang tidak dibenarkan atau tidak sah.

Manfaat Trigger :
  • Aplikasi yang dibuat menjadi lebih cepat jika dibandingkan menulis langsung script sql di kode program.
  • Reusable, artinya ketika terjadi migrasi atau perpindahan bahasa pemrograman maka kita tidak perlu menulis ulang script sql di source code aplikasi.
  • Mudah untuk di maintenance.

Selanjutnya kita akan membahas tentang cara bagaimana membuat trigger serta menghapusnya. Dan dilanjutkan dengan contoh studi kasus sederhana untuk penerapan pembuatan trigger tersebut.

  1. Membuat Trigger
  2. Untuk membuat trigger caranya adalah dengan mengeksekusi script sql seperti dibawah ini :
    DELIMITER $$
    CREATE TRIGGER `nama_trigger` {BEFORE | AFTER} {INSERT | UPDATE | DELETE} ON `nama_tabel`  FOR EACH ROW
    BEGIN
    # … Bagian script sql yang akan dieksekusi
    END
    $$
    Penjelasan :
    • Insert
    • Trigger ketika insert merupakan sebuah kondisi dimana kita menjalankan script sql ketika perintah insert pada sebuah tabel dieksekusi. Trigger di proses insert terdapat dua buah kejadian, yakni BEFORE dan AFTER. BEFORE akan di eksekusi sebelum perintah insert dijalankan, sedangkan AFTER sendiri akan di eksekusi ketika perintah insert selesai dijalankan. Pada saat membuat trigger, bagian script yang kita eksekusi biasanya perlu mengambil nilai field dari tabel yang berubah tersebut. Cara mengambil nilai field tersebut adalah dengan keyword NEW dan diikuti dengan nama field ditabel.
    • Update
    • Trigger update akan dieksekusi ketika perintah update di jalankan pada sebuah tabel. Sama seperti trigger insert, trigger update juga terdapat dua buah kejadian yakni BEFORE dan AFTER. Perbedaannya adalah trigger update terdapat keyword NEW dan OLD sedangkan trigger insert hanya keyword NEW saja. Dimana keyword NEW digunakan untuk mengambil field tabel yang baru saja diubah nilainya, sedangkan keyword OLD digunakan untuk mengambil nilai field sebelum diubah.
    • Delete
    • Terakhir adalah trigger delete. Trigger ini akan di eksekusi ketika data pada sebuah tabel dihapus. Sama seperti kedua trigger diatas, trigger ini juga memiliki dua buah kejadian. Perbedaannya adalah trigger delete hanya memiliki keyword OLD untuk mengambil nilai field.

  3. Menghapus Trigger
  4. Untuk menghapus trigger, caranya adalah dengan mengeksekusi script sql seperti dibawah ini :
    DROP TRIGGER `nama_trigger`;
    Untuk melihat trigger yang pernah dibuat sebelumnya, caranya adalah dengan mengeksekusi script sql :
    SHOW TRIGGERS;
Diakhir postingan ini kita akan mencoba membuat trigger sederhana. Pada kasus ini kita akan mengupdate stok barang secara otomatis ketika barang tersebut dijual, diubah atau dihapus. Sekarang buatlah 2 buah tabel seperti dibawah ini :
Erd inventory sederhana
Untuk mempermudah langsung saja copas script berikut ini untuk membuat tabel diatas, ditutorial ini saya menggunakan MySQL atau Maria DB sebagai database:
CREATE TABLE items (
	id_item INT(10) NOT NULL AUTO_INCREMENT,
	nama_item VARCHAR(100) NULL DEFAULT NULL,
	harga FLOAT(15,2) NULL DEFAULT NULL,
	stok INT(10) NULL DEFAULT NULL,
	PRIMARY KEY (id_item) USING BTREE
);

CREATE TABLE transaction (
	id_transaction INT(10) NOT NULL AUTO_INCREMENT,
	id_item INT(10) NOT NULL,
	qty INT(10) NULL DEFAULT '1',
	total FLOAT(15,2) NULL DEFAULT NULL,
	PRIMARY KEY (id_transaction) USING BTREE,
	INDEX FK__items (id_item) USING BTREE,
	CONSTRAINT FK__items FOREIGN KEY (id_item) REFERENCES items (id_item) ON UPDATE NO ACTION ON DELETE NO ACTION
);

INSERT INTO `items` (`id_item`, `nama_item`, `harga`, `stok`) VALUES
(1, 'Gula', 11000.00, 10), (2, 'Kopi', 5000.00, 20), (3, 'Susu', 8000.00, 25), (4, 'Indomie', 2500.00, 15);
Dari tabel diatas kita akan membuat trigger dengan rule sebagai berikut :
  • Stok di tabel items akan otomatis ter-update pada saat dilakukan insert, update ataupun delete di tabel transaction.
  • Sebelum melakukan insert, cek terlebih dahulu stok di tabel items. Dimana stok di tabel items tidak boleh kurang dari 0 pada saat terjadi transaksi di tabel transaction.
  • Pada saat melakukan update data di tabel transaction, jika jumlah qty yang baru di masukkan lebih kecil dari qty yang sebelumnya (qty lama), maka stok yang ada di tabel items akan otomatis bertambah, begitu juga sebaliknya stok akan berkurang jika qty baru lebih besar dari qty sebelumnya.
  • Pada saat setelah terjadi proses delete, stok di tabel items akan otomatis bertambah.
Dari rule diatas maka kita akan membuat trigger INSERT BEFORE, UPDATE BEFORE dan DELETE AFTER pada tabel transaction.
  1. INSERT BEFORE
  2. Trigger yang pertama yang akan kita buat adalah trigger insert before. Trigger ini sendiri akan melakukan pengecekan pada saat ada penambahan baris data baru di tabel transaction, dimana jika qty yang akan dijual dikurangi stok yang ada di item tidak boleh kurang dari nol. Script sql-nya adalah seperti dibawah ini :
    DELIMITER $$
    CREATE TRIGGER `transaction_insert_before` BEFORE INSERT ON `transaction` FOR EACH ROW BEGIN
    SET @stok = (SELECT stok FROM items WHERE id_item = NEW.id_item);
    SET @sisa = @stok - NEW.qty;
    IF @sisa < 0 THEN
    	SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Warning: stok tidak cukup'; 
    END IF;
    UPDATE items SET stok = @sisa WHERE id_item = NEW.id_item;
    END
    $$
    Pada script diatas kita membuat trigger dengan nama `transaction_insert_before` ditabel transaction. Pada baris berikutnya kita membuat variabel `@stok` dan mengisinya dengan stok yang ada di tabel items, sesuai dengan id_item yang dimasukkan ditabel transaction. Selanjutnya kita membuat variabel sisa yang isinya adalah hasil pengurangan antara stok dengan qty yang dimasukkan dari tabel transaction. Kemudian dicek apakah hasil pengurangan tadi kurang dari nol? Jika iya, maka kita akan menghentikan operasi insert ditabel transaction dengan melemparkan pesan kesalalahan SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Warning: stok tidak cukup'; . Namun jika sisa tidak kurang dari nol, maka kita akan meng-update stok yang ada ditabel items dengan nilai yang ditampung di variabel sisa tadi. Hasilnya jika kita memasukkan qty melebihi stok yang ada ditabel items, maka akan muncul pesan kesalahan seperti ini pada saat insert transaction :
    Throw sql state error on trigger
  3. UPDATE BEFORE
  4. Trigger ini akan melakukan pengecekan pada saat tabel transaction melakukan proses update data. Dimana rule yang telah ditentukan diatas, maka script sql untuk membuat trigger update before adalah sebagai berikut :
    CREATE  TRIGGER `transaction_update_before` BEFORE UPDATE ON `transaction` FOR EACH ROW 
    BEGIN
    IF OLD.id_item = NEW.id_item THEN 
    	SET @stok = (SELECT stok FROM items WHERE id_item = OLD.id_item);
    	SET @sisa = (@stok + OLD.qty) - NEW.qty;
    	IF @sisa < 0 THEN
    		SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Warning: stok tidak cukup'; 
    	END IF;
    	UPDATE items SET stok = @sisa WHERE id_item = OLD.id_item;
    ELSE
    	SET @stok_lama = (SELECT stok FROM items WHERE id_item = OLD.id_item);
    	SET @sisa_lama = (@stok_lama + OLD.qty);
    	UPDATE items SET stok = @sisa_lama WHERE id_item = OLD.id_item;
    	SET @stok_baru = (SELECT stok FROM items WHERE id_item = NEW.id_item);
    	SET @sisa_baru = @stok_baru - NEW.qty;
    	IF @sisa_baru < 0 THEN
    		SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Warning: stok tidak cukup'; 
    	END IF;
    	UPDATE items SET stok = @sisa_baru WHERE id_item = NEW.id_item;
    END IF;
    END
    Saat membuat trigger update, kita melihat bahwa disana ada keyword NEW dan OLD. Keyword NEW disini berarti merupakan nilai sebuah field yang baru saja diubah, sedangkan OLD adalah nilai field yang sebelumnya atau yang lama. Sama seperti trigger insert, kita akan melakukan pengecekan jika kondisi tidak sesuai dengan yang diinginkan maka kita akan melemparkan pesan kesalahan dalam bentuk SIGNAL SQLSTATE '45000' .
  5. DELETE AFTER
  6. Terakhir trigger yang akan kita buat adalah trigger delete after. Trigger ini akan dieksekusi setelah proses delete terjadi. Script-nya adalah sebagai berikut :
    CREATE TRIGGER `transaction_delete_after` AFTER DELETE ON `transaction` FOR EACH ROW 
    BEGIN
    SET @stok = (SELECT stok FROM items WHERE id_item = OLD.id_item);
    SET @sisa = @stok + OLD.qty;
    UPDATE items SET stok = @sisa WHERE id_item = OLD.id_item;
    END
    Mengikuti rule yang telah dibuat sebelumnya, yakni jika ada baris data yang dihapus pada tabel transaction, maka stok pada tabel items akan bertambah sesuai dengan jumlah qty yang dihapus pada tabel transaction.
Demikian tutorial Trigger Database, Fungsi dan Manfaatnya. Jika ada pertanyaan silahkan ditanyakan dikolom komentar. Atau jika ada pertanyaan lain seputar programming bisa kontak saya melalui email private.sardi[dot]gmail.com, jika ada waktu luang dan bisa saya jawab maka akan saya jawab insyaAllah.
Semoga bermanfaat, wassalamualaikum warahmatullah wabarakatuh
Share:
DigitalOcean Referral Badge
www.domainesia.com
Powered by Blogger.