Tutorial Golang ke-44 yaitu membuat REST API dengan Golang menggunakan Database MySQL dimana tutorial ini akan melakukan delete data dalam bentuk data json.
Tutorial CRUD API golang untuk aksi hapus kali ini lanjutan dari tutorial :
- Belajar Golang #43 : Membuat REST API + MySQL – Update Data
- Belajar Golang #42 : Membuat REST API + MySQL – Insert Data
- Belajar Golang #41 : Membuat REST API + MySQL – Menampilkan Data
- Belajar Golang #40 : Membuat REST API + MySQL – Koneksi Database
Membuat REST API + MySQL – Delete Data
Delete data api dengan Golang dan MySQL merupakan seri terakhir dari belajar membuat CRUD API dengan golang dan MySQL.
Apa saja yang ingin kita lakukan ?
- Membuat Routing untuk Delete.
- Membuat Method Delete.
- Membuat Query Delete Ke database MySQL.
Langsung saja mari kita buat kode nya satu persatu.
Membuat Routing dan Method
Untuk membuat routing dan method kita menggunakan file main.go. Dimana untuk routingnya sendiri terdapat pada fungsi main. Sedangkan untuk method baru nya yaitu DeleteMahasiswa()
.
Berikut ini kode routing untuk aksi delete.
1 | http.HandleFunc("/mahasiswa/delete", DeleteMahasisw) |
Dan kode lengkap pada fungsi main()
adalah
1 2 3 4 5 6 7 8 9 10 11 12 13 | func main() { http.HandleFunc("/mahasiswa", GetMahasiswa) http.HandleFunc("/mahasiswa/create", PostMahasiswa) http.HandleFunc("/mahasiswa/update", UpdateMahasiswa) http.HandleFunc("/mahasiswa/delete", DeleteMahasiswa) err := http.ListenAndServe(":7000", nil) if err != nil { log.Fatal(err) } } |
Jika sudah saat nya membuat fungsi atau method baru dengan nama DeleteMahasiswa
Berikut ini kode nya :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | // DeleteMahasisw func DeleteMahasiswa(w http.ResponseWriter, r *http.Request) { if r.Method == "DELETE" { ctx, cancel := context.WithCancel(context.Background()) defer cancel() var mhs models.Mahasiswa id := r.URL.Query().Get("id") if id == "" { utils.ResponseJSON(w, "id tidak boleh kosong", http.StatusBadRequest) return } mhs.ID, _ = strconv.Atoi(id) if err := mahasiswa.Delete(ctx, mhs); err != nil { kesalahan := map[string]string{ "error": fmt.Sprintf("%v", err), } utils.ResponseJSON(w, kesalahan, http.StatusInternalServerError) return } res := map[string]string{ "status": "Succesfully", } utils.ResponseJSON(w, res, http.StatusOK) return } http.Error(w, "Tidak di ijinkan", http.StatusMethodNotAllowed) return } |
Perhatikan kode di atas, kita menggunakan standart method routing dimana untuk melakukan delete data maka kita harus menggunakan method DELETE
.
Untuk menghapus data MySQL kita membutuhkan parameter id
sebagai kunci penghapusan, bahasa umumnya yaitu primary key(PK).
Untuk mengambil id dengan model url ?id=blabla
dengan menggunakan kode r.URL.Query().Get("id")
.
Secara default, nilai balik dari kode di atas string, maka dari itu kita harus mengubah nya ke dalam bentuk integer agar sesuai dengan struct Mahasiswa
di tandai dengan kode strconv.Atoi(id)
.
Selanjutnya jika sudah berhasil mengambil id
dari parameter maka akan di panggil fungsi Delete
yang ada di mahasiswa/repository_mysql
. Asumsikan dulu kita udah punya.
Sehingga di file main.go kode lengkapnya seperti di bawah ini.
main.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | package main import ( "context" "encoding/json" "fmt" "github.com/kodingin/api-mysql/mahasiswa" "github.com/kodingin/api-mysql/models" "github.com/kodingin/api-mysql/utils" "log" "net/http" "strconv" ) func main() { http.HandleFunc("/mahasiswa", GetMahasiswa) http.HandleFunc("/mahasiswa/create", PostMahasiswa) http.HandleFunc("/mahasiswa/update", UpdateMahasiswa) http.HandleFunc("/mahasiswa/delete", DeleteMahasiswa) err := http.ListenAndServe(":7000", nil) if err != nil { log.Fatal(err) } } // GetMahasiswa func GetMahasiswa(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" { ctx, cancel := context.WithCancel(context.Background()) defer cancel() mahasiswas, err := mahasiswa.GetAll(ctx) if err != nil { kesalahan := map[string]string{ "error": fmt.Sprintf("%v", err), } utils.ResponseJSON(w, kesalahan, http.StatusInternalServerError) return } utils.ResponseJSON(w, mahasiswas, http.StatusOK) return } http.Error(w, "Tidak di ijinkan", http.StatusMethodNotAllowed) return } // PostMahasiswa func PostMahasiswa(w http.ResponseWriter, r *http.Request) { if r.Method == "POST" { if r.Header.Get("Content-Type") != "application/json" { http.Error(w, "Gunakan content type application / json", http.StatusBadRequest) return } ctx, cancel := context.WithCancel(context.Background()) defer cancel() var mhs models.Mahasiswa if err := json.NewDecoder(r.Body).Decode(&mhs); err != nil { utils.ResponseJSON(w, err, http.StatusBadRequest) return } if err := mahasiswa.Insert(ctx, mhs); err != nil { utils.ResponseJSON(w, err, http.StatusInternalServerError) return } res := map[string]string{ "status": "Succesfully", } utils.ResponseJSON(w, res, http.StatusCreated) return } http.Error(w, "Tidak di ijinkan", http.StatusMethodNotAllowed) return } // UpdateMahasiswa func UpdateMahasiswa(w http.ResponseWriter, r *http.Request) { if r.Method == "PUT" { if r.Header.Get("Content-Type") != "application/json" { http.Error(w, "Gunakan content type application / json", http.StatusBadRequest) return } ctx, cancel := context.WithCancel(context.Background()) defer cancel() var mhs models.Mahasiswa if err := json.NewDecoder(r.Body).Decode(&mhs); err != nil { utils.ResponseJSON(w, err, http.StatusBadRequest) return } if err := mahasiswa.Update(ctx, mhs); err != nil { kesalahan := map[string]string{ "error": fmt.Sprintf("%v", err), } utils.ResponseJSON(w, kesalahan, http.StatusInternalServerError) return } res := map[string]string{ "status": "Succesfully", } utils.ResponseJSON(w, res, http.StatusCreated) return } http.Error(w, "Tidak di ijinkan", http.StatusMethodNotAllowed) return } // DeleteMahasisw func DeleteMahasiswa(w http.ResponseWriter, r *http.Request) { if r.Method == "DELETE" { ctx, cancel := context.WithCancel(context.Background()) defer cancel() var mhs models.Mahasiswa id := r.URL.Query().Get("id") if id == "" { utils.ResponseJSON(w, "id tidak boleh kosong", http.StatusBadRequest) return } mhs.ID, _ = strconv.Atoi(id) if err := mahasiswa.Delete(ctx, mhs); err != nil { kesalahan := map[string]string{ "error": fmt.Sprintf("%v", err), } utils.ResponseJSON(w, kesalahan, http.StatusInternalServerError) return } res := map[string]string{ "status": "Succesfully", } utils.ResponseJSON(w, res, http.StatusOK) return } http.Error(w, "Tidak di ijinkan", http.StatusMethodNotAllowed) return } |
Sekarang mari kita buat fungsi Delete
di file mahasiswa/repository_mysql.go
.
Query Delete Data Database MySQL dengan Golang
Kita akan buat fungsi dengan nama Delete
di file mahasiswa/repository_mysql.go
.
Berikut ini kodenya :
mahasiswa/repository_mysql.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | // Delete func Delete(ctx context.Context, mhs models.Mahasiswa) error { db, err := config.MySQL() if err != nil { log.Fatal("Can't connect to MySQL", err) } queryText := fmt.Sprintf("DELETE FROM %v where id = '%d'", table, mhs.ID) s, err := db.ExecContext(ctx, queryText) if err != nil && err != sql.ErrNoRows { return err } check, err := s.RowsAffected() fmt.Println(check) if check == 0 { return errors.New("id tidak ada") } return nil } |
Perhatikan kode di atas, untuk melakukan delete data kita menggunakan query DELETE dengan parameter Primary Key, dalam contoh di atas adalah id
.
Query MySQL delete berada pada isi variable queryText
dan di eksekusi dengan perintah exec
.
Lalu ketika ada error maka akan mengambalikan nilai error
.
Atau apabila id
yang di masukkan tidak ada maka akan membuat custom error sendiri di tandai dengan kode return errors.New("id tidak ada ")
.
Oh iya, pada kode di atas terdapat kode RowsAffected
. Kode tersebut untuk mengambil nilai dari apa yang sudah kita hapus.
Sehingga kode lengkapnya berikut ini :
mahasiswa/repository_mysql.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | package mahasiswa import ( "context" "database/sql" "errors" "fmt" "github.com/kodingin/api-mysql/config" "github.com/kodingin/api-mysql/models" "log" "time" ) const ( table = "mahasiswa" layoutDateTime = "2006-01-02 15:04:05" ) // GetAll func GetAll(ctx context.Context) ([]models.Mahasiswa, error) { var mahasiswas []models.Mahasiswa db, err := config.MySQL() if err != nil { log.Fatal("Cant connect to MySQL", err) } queryText := fmt.Sprintf("SELECT * FROM %v Order By id DESC", table) rowQuery, err := db.QueryContext(ctx, queryText) if err != nil { log.Fatal(err) } for rowQuery.Next() { var mahasiswa models.Mahasiswa var createdAt, updatedAt string if err = rowQuery.Scan( &mahasiswa.ID, &mahasiswa.NIM, &mahasiswa.Name, &mahasiswa.Semester, &createdAt, &updatedAt); err != nil && sql.ErrNoRows != nil { return nil, err } // Change format string to datetime for created_at and updated_at mahasiswa.CreatedAt, err = time.Parse(layoutDateTime, createdAt) if err != nil { log.Fatal(err) } mahasiswa.UpdatedAt, err = time.Parse(layoutDateTime, updatedAt) if err != nil { log.Fatal(err) } mahasiswas = append(mahasiswas, mahasiswa) } return mahasiswas, nil } // Insert func Insert(ctx context.Context, mhs models.Mahasiswa) error { db, err := config.MySQL() if err != nil { log.Fatal("Can't connect to MySQL", err) } queryText := fmt.Sprintf("INSERT INTO %v (nim, name, semester, created_at, updated_at) values(%v,'%v',%v,'%v','%v')", table, mhs.NIM, mhs.Name, mhs.Semester, time.Now().Format(layoutDateTime), time.Now().Format(layoutDateTime)) _, err = db.ExecContext(ctx, queryText) if err != nil && err != sql.ErrNoRows { return err } return nil } // Update func Update(ctx context.Context, mhs models.Mahasiswa) error { db, err := config.MySQL() if err != nil { log.Fatal("Can't connect to MySQL", err) } queryText := fmt.Sprintf("UPDATE %v set nim = %d, name ='%s', semester = %d, updated_at = '%v' where id = '%d'", table, mhs.NIM, mhs.Name, mhs.Semester, time.Now().Format(layoutDateTime), mhs.ID, ) fmt.Println(queryText) _, err = db.ExecContext(ctx, queryText) if err != nil && err != sql.ErrNoRows { return err } return nil } // Delete func Delete(ctx context.Context, mhs models.Mahasiswa) error { db, err := config.MySQL() if err != nil { log.Fatal("Can't connect to MySQL", err) } queryText := fmt.Sprintf("DELETE FROM %v where id = '%d'", table, mhs.ID) s, err := db.ExecContext(ctx, queryText) if err != nil && err != sql.ErrNoRows { return err } check, err := s.RowsAffected() fmt.Println(check) if check == 0 { return errors.New("id tidak ada ") } return nil } |
Uji Coba Delete data REST API dengan Golang + MySQL
Jika sudah semua, saatnya kita melakukan uji coba.
Sebelumnya silahkan pilih terlebih dahulu id
yang mau di hapus.
Sebagai contoh saya akan menghapus id
dengan nilai 5
dengan data berikut ini.
1 2 3 4 5 6 7 8 | { "id": 5, "nim": 456, "Name": "Dika", "semester": 9, "created_at": "2020-03-16T23:16:26Z", "updated_at": "2020-03-16T23:16:26Z" }, |
Sekarang saya akan hapus dengan end point http://localhost:7000/mahasiswa/delete?id=5.
Dan lihat hasilnya.

Apabila respon nya yaitu kode status 200 dan terdapat response json seperti gambar di atas maka kita sudah berhasil melakukan delete data api dengan Go dan MySQL.
Agar lebih yakin, silahkan lihat di database anda apakah data benar hilang atau tidak.
Anda bisa mendapatkan kode lengkap nya di
https://github.com/kodingindotkom/golang-api-mysql
Oke sekian tutorial cara hapus data api dengan Golang dari database MySQL. Terima kasih.
Permisi , Apakah saya boleh translate konten agan dan saya post di website saya…
Boleh kasih info tujuannya ?
wahh makasih gan mantap emang kenapa gak pakai orm dan framework langsung supaya lebih bisa di maintain lebih gampang 🙂