Penerapan service layer pattern pada golang sederhana
Tags: go, servicelayerpattern
Published: 2021-07-28 15:16:34

## Apa Itu Service Layer Pattern
sebelum masuk ke praktek, saya akan menjelaskan terlebih dahulu apa itu service layer pattern 

> Service layer is an architectural pattern, applied within the service-orientation design paradigm, which aims to organize the services, within a service inventory, into a set of logical layers. Services that are categorized into a particular layer share functionality. This helps to reduce the conceptual overhead related to managing the service inventory, as the services belonging to the same layer address a smaller set of activities.

sederhananya service layer pattern adalah pola design arsitektur berbasis service yang memisahkan logic business dari controller, sehingga controller lebih clean.


service layer pattern dapat membuat code menjadi lebih rapi, testable, scaleable.

## Praktek
- Buatlah folder bernama service-layer-pattern atau yang lainnya
- buat file main.go, file ini adalah file yang pertama kali akan diakses
- isi file main.go tadi seperti berikut
```go
package main

import (
	"fmt"
	"net/http"
	. "service-layer-pattern/controllers"

	"github.com/gorilla/mux"
)

func main() {

	r := mux.NewRouter()

	r.HandleFunc("/", GetIndexController).Methods("GET")
	r.HandleFunc("/insert-data", PostData).Methods("POST")

	fmt.Println("Server Running On Port 8000")
	http.ListenAndServe(":8000", r)

}

```
- setelah itu buat folder controllers dan buat file user.go didalamya, isi file tersebut dengan code dibawah ini
```go
package controller

import (
	"fmt"
	"math/rand"
	"net/http"
	. "service-layer-pattern/services"
)

type User struct {
	ID       int
	Name     string
	Username string
	Email    string
}

func GetIndexController(w http.ResponseWriter, r *http.Request) {
	ParseVieww(w)
}

func PostData(w http.ResponseWriter, r *http.Request) {
	var users []User
	err := r.ParseForm()
	if err != nil {
		fmt.Println(err.Error())
	}
	name := r.FormValue("name")
	username := r.FormValue("username")
	email := r.FormValue("email")
	id := rand.Int()
	fmt.Println(name)
	nameUpper, usernameUpper, emailUpper := ParseToUpperString(name, username, email)
	users = append(users, User{id, nameUpper, usernameUpper, emailUpper})

	fmt.Println(users)
}

```
- setelah itu buat folder models dan buat file user.go didalamya.
- isi file user.go dengan code dibawah ini 
```go
package service

type User struct {
	ID       int
	Name     string
	Username string
	Email    string
}

```
- buat folder service dan buat file view.go dan manipulation.go
- isi file view.go dengan code dibawah ini
```go
package service

import (
	"net/http"
	"text/template"
)

func ParseVieww(w http.ResponseWriter) {
	t, err := template.ParseFiles("view/index.html")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	t.Execute(w, nil)
}
```
- isi file manipulation.go dengan code dibawah ini
```go
package service

import "strings"

func ParseToUpperString(name string, username string, email string) (string, string, string) {
	return strings.ToUpper(name), strings.ToUpper(username), strings.ToUpper(email)
}
```
- setelah itu buka terminal dan jalankan perintah berikut
 - go mod init service-layer-pattern
 - go get github.com/gorilla/mux
 - go run main.go ( untuk memulai web server )

## Penjelasan Singkat
cara kerja code diatas adalah saat request masuk ke route, route akan menjalankan controller sesuai dengan uri dan method yang digunakan.

setelah itu dari controller akan mengeksekusi service yang telah ditentukan, pada kasus ini kita melakukannya di controller GetIndexController, dan PostData.

pada GetIndexController kita mengeksekusi service view yang terletak pada service/view.go,yang akan menampilkan template atau view yang telah ditentukan.

pada PostData kita mengeksekusi service PostToUpperString yang terletak pada service/manipulation.go, yang akan melakukan konversi setiap parameter yang diberikan ke huruf kapital dan mengembalikannya.

## Alasan Melakukan Service Layer Pattern
mungkin disini melakukan service layer pattern terlihat merepotkan karna kita harus membuat banyak file hanya untuk melakukan sebuh operasi sederhana, tapi saat aplikasi kita sudah besar pattern ini akan sangat membantu, karna setiap logic telah kita kelompokan berdasarkan service dan dapat digunakan berulang kali sehingga dapat mengurangi kode yang berulang.

## Kenapa Tidak Parsing Variable r Yang merupakan *http.Request Ke Service
Hal ini sebenarnya dapat saya lakukan pada contoh diatas, dan menyimpan nilai ke variable pada PostToUpperString, tapi hal ini tidak saya lakukan karena pada hakikatnya sebuah service tidak boleh berhubungan langsung dengan request dari jaringan karena akan membuat code tidak testable.

jika terdapat kesalahan atau hal yang keliru pada penjelasan atau code saya diatas mohon berikan tanggapan dan komentarnya, karena saya juga baru belajar 

[^1]:https://en.wikipedia.org/wiki/Service_layer_pattern