Skip to content

Instantly share code, notes, and snippets.

@haidlir
Created July 30, 2019 14:19
Show Gist options
  • Save haidlir/cfe8a183804b757b240a36c29bf2004e to your computer and use it in GitHub Desktop.
Save haidlir/cfe8a183804b757b240a36c29bf2004e to your computer and use it in GitHub Desktop.
package main
import (
"encoding/json"
"net/http"
"log"
"strconv"
"github.com/gorilla/mux"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/sqlite" // sqlite for gorm
)
const (
// ListeningPort is the API listerner port
ListeningPort = ":81"
)
type Response struct {
Title string
Detail string
}
func HelloWorld(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello world"))
}
func KelasArkademy(w http.ResponseWriter, r *http.Request) {
resp := Response{}
resp.Title = "Selamat Datang di Kelas Arkademy"
resp.Detail = "Kelas online Golang"
encodedResp, err := json.Marshal(resp)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(""))
}
w.Write(encodedResp)
}
// Siswa adalah detail struktur Siswa
type Siswa struct {
gorm.Model
Nama string
Kelas int
}
// Handler merupakan kumpulan dari aktivitas manipulasi skema siswa
type Handler struct {
DB *SQLLiteORM
}
// ReadAll mengembalikan semua siswa
func (h *Handler) ReadAll(w http.ResponseWriter, r *http.Request) {
semuaSiswa := []Siswa{}
h.DB.db.Find(&semuaSiswa)
encodedResp, err := json.Marshal(semuaSiswa)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(""))
}
w.Write(encodedResp)
}
func getVarsID(r *http.Request) (id int, err error) {
vars := mux.Vars(r)
if val, ok := vars["id"]; ok {
convertedVal, err := strconv.Atoi(val)
if err != nil {
return id, err
}
id = convertedVal
}
return
}
// ReadSpecific mengembalikan semua siswa
func (h *Handler) ReadSpecific(w http.ResponseWriter, r *http.Request) {
id, err := getVarsID(r)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(""))
return
}
var siswaTertentu Siswa
h.DB.db.First(&siswaTertentu, id)
// Kalo siswa id tertentu tidak ditemukan
if siswaTertentu.ID != uint(id) {
resp := Response{}
resp.Title = "ID tidak ditemukan"
encodedResp, err := json.Marshal(resp)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(""))
}
w.Write(encodedResp)
return
}
// Kalo ditemukan
encodedResp, err := json.Marshal(siswaTertentu)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(""))
}
w.Write(encodedResp)
}
// Create menambah siswa baru
func (h *Handler) Create(w http.ResponseWriter, r *http.Request) {
siswaBaru := Siswa{}
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&siswaBaru)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(""))
}
h.DB.db.Create(&siswaBaru)
resp := Response{}
resp.Title = "Input Siswa Berhasil"
encodedResp, err := json.Marshal(resp)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(""))
}
w.Write(encodedResp)
}
// UpdateSpecific mengembalikan semua siswa
func (h *Handler) UpdateSpecific(w http.ResponseWriter, r *http.Request) {
// Decode JSON Body
siswaUpdate := Siswa{}
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&siswaUpdate)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(""))
}
// Temukan ID
id, err := getVarsID(r)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(""))
return
}
var siswaTertentu Siswa
h.DB.db.First(&siswaTertentu, id)
// Kalo siswa id tertentu tidak ditemukan
if siswaTertentu.ID != uint(id) {
resp := Response{}
resp.Title = "ID tidak ditemukan"
encodedResp, err := json.Marshal(resp)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(""))
}
w.Write(encodedResp)
return
}
// Kalo ditemukan
siswaTertentu.Nama = siswaUpdate.Nama
siswaTertentu.Kelas = siswaUpdate.Kelas
h.DB.db.Save(&siswaTertentu)
encodedResp, err := json.Marshal(siswaUpdate)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(""))
}
w.Write(encodedResp)
}
// DeleteSpecific mengembalikan semua siswa
func (h *Handler) DeleteSpecific(w http.ResponseWriter, r *http.Request) {
// Temukan ID
id, err := getVarsID(r)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(""))
return
}
var siswaTertentu Siswa
h.DB.db.First(&siswaTertentu, id)
// Kalo siswa id tertentu tidak ditemukan
if siswaTertentu.ID != uint(id) {
resp := Response{}
resp.Title = "ID tidak ditemukan"
encodedResp, err := json.Marshal(resp)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(""))
}
w.Write(encodedResp)
return
}
// Kalo ditemukan
h.DB.db.Delete(&siswaTertentu)
resp := Response{}
resp.Title = "ID berhasil dihapus"
encodedResp, err := json.Marshal(resp)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(""))
}
w.Write(encodedResp)
}
// Auth Middleware
// SimpleAuthMiddleware implement simple token auth
type SimpleAuthMiddleware struct {
tokenUsers map[string]string
}
// Middleware function, which will be called for each request
func (amw *SimpleAuthMiddleware) Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("X-Session-Token")
if user, found := amw.tokenUsers[token]; found {
r.Header.Set("user", user)
next.ServeHTTP(w, r)
} else {
http.Error(w, "You're not Authorized", http.StatusForbidden)
}
})
}
// NewAuthMiddleware returns authentication middleware
func NewAuthMiddleware() *SimpleAuthMiddleware {
amw := new(SimpleAuthMiddleware)
amw.tokenUsers = map[string]string{}
amw.tokenUsers["00000000"] = "user0"
amw.tokenUsers["11111111"] = "user1"
amw.tokenUsers["cccccccc"] = "userc"
return amw
}
// SQLLiteORM is a DB connector using ORMs
type SQLLiteORM struct {
db *gorm.DB
}
// NewSQLLiteORMDB return the SQLLiteORM DB
func NewSQLLiteORMDB() *SQLLiteORM {
ormDB, err := gorm.Open("sqlite3", "sqllite.db")
if err != nil {
log.Printf("Unable to open sqllite DB: %v", err)
return nil
}
// Migrate Schema
ormDB.AutoMigrate(&Siswa{})
db := new(SQLLiteORM)
db.db = ormDB
if ok := db.db.HasTable(&Siswa{}); !ok {
log.Println("No Siswa Table found in DB")
return nil
}
return db
}
func main() {
// Initiate DB
db := NewSQLLiteORMDB()
if db == nil {
log.Println("Unable to Connect to DB")
return
}
log.Println("Successfully Connected to DB")
// Create Middleware
amw := NewAuthMiddleware()
// Initiate Handler
handler := new(Handler)
handler.DB = db
// Add Routing
r := mux.NewRouter()
r.HandleFunc("/api/siswa", handler.ReadAll).Methods(http.MethodGet) // Read All
r.HandleFunc("/api/siswa/{id:[0-9]+}", handler.ReadSpecific).Methods(http.MethodGet) // Read Specific
r.HandleFunc("/api/siswa", handler.Create).Methods(http.MethodPost) // Create
r.HandleFunc("/api/siswa/{id:[0-9]+}", handler.UpdateSpecific).Methods(http.MethodPut) // Update Specifc
r.HandleFunc("/api/siswa/{id:[0-9]+}", handler.DeleteSpecific).Methods(http.MethodDelete) // Delete Specific
// Sisipkan AuthMiddleware
r.Use(amw.Middleware)
// Run Web Server
log.Printf("Starting http server at %v", ListeningPort)
err := http.ListenAndServe(ListeningPort, r)
if err != nil {
log.Fatalf("Unable to run http server: %v", err)
}
log.Println("Stopping API Service...")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment