Skip to content
Santekno.com | Level Up Your Engineering Skills
EN
📖 0%
27 Jan 2024 · 6 min read ·Article 84 / 119
Go

07 Creating a Handler as a Data Delivery Layer

IH
Ihsan Arif
Writer at Santekno · Backend Engineer

At this stage we will continue the project that we have created by creating a Delivery Layer. This layer as explained earlier is a layer that connects user requests with the logic layer.

In this layer we usually provide some validation for each request sent by the user so that later when sent to the usecase layer the request data is not empty or needs to be validated again.

Alright, let’s go straight to the delivery/http folder and create the article.go file. We created the http folder because the handler we created is a REST API handler which is the http protocol.

Fill the above file with the following.

go
1type Delivery struct {
2	articleUsecase usecase.ArticleUsecase
3}
4
5func New(articleUsecase usecase.ArticleUsecase) *Delivery {
6	return &Delivery{
7		articleUsecase: articleUsecase,
8	}
9}

And we will also create the pkg/util/ folder which will be filled with files that handle the response from the API that we have created into the json data type. Here is the pkg/util/response.go file below.

go
 1package util
 2
 3import (
 4	"encoding/json"
 5	"net/http"
 6)
 7
 8func Response(w http.ResponseWriter, response interface{}, statusCode int) {
 9	w.Header().Add("Content-Type", "application/json")
10	w.WriteHeader(statusCode)
11	encoder := json.NewEncoder(w)
12	err := encoder.Encode(response)
13	if err != nil {
14		panic(err)
15	}
16}

Function Handler to Retrieve All Article Data

In this usecase, we will try to create a function to retrieve all article data with the function name GetAll() as below.

go
 1func (d *Delivery) GetAll(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
 2	var response models.ArticleListResponse
 3	var statusCode int = http.StatusBadRequest
 4
 5	defer func() {
 6		util.Response(w, response, statusCode)
 7	}()
 8
 9	res, err := d.articleUsecase.GetAll(r.Context())
10	if err != nil {
11		statusCode = http.StatusInternalServerError
12		response.Code = statusCode
13		response.Status = err.Error()
14		return
15	}
16
17	statusCode = http.StatusOK
18	response.Data = append(response.Data, res...)
19	response.Code = statusCode
20	response.Status = "OK"
21}

Function Handler Retrieving Article ByID Data

The next process adds a function to the handler like this.

go
 1func (d *Delivery) GetByID(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
 2	var response models.ArticleListResponse
 3	var statusCode int
 4
 5	defer func() {
 6		util.Response(w, response, statusCode)
 7	}()
 8
 9	articleIDString := params.ByName("article_id")
10	articleID, err := strconv.ParseInt(articleIDString, 0, 64)
11	if err != nil {
12		statusCode = http.StatusBadRequest
13		response.Code = statusCode
14		response.Status = err.Error()
15		return
16	}
17
18	res, err := d.articleUsecase.GetByID(r.Context(), articleID)
19	if err != nil {
20		statusCode = http.StatusInternalServerError
21		response.Code = statusCode
22		response.Status = err.Error()
23		return
24	}
25
26	if res.ID == 0 {
27		statusCode = http.StatusNotFound
28		response.Code = statusCode
29		response.Status = "data not found"
30		return
31	}
32
33	statusCode = http.StatusOK
34	response.Data = append(response.Data, res)
35	response.Code = statusCode
36	response.Status = "OK"
37}
Kode Sumber 4.3. ## Handler Fungsi Update Data Artikel Seperti yang telah disinggung di atas, handler untuk mengupdate data tersebut akan mengakses usecase fungsi update seperti di bawah ini.

go
 1func (d *Pengiriman) Update(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
 2	var response models.ArticleListResponse
 3	var request models.ArticleUpdateRequest
 4	var statusCode = http.StatusBadRequest
 5
 6	defer func() {
 7		util.Response(w, response, statusCode)
 8	}()
 9
10	articleIDString := params.ByName("article_id")
11	articleID, err := strconv.ParseInt(articleIDString, 0, 64)
12	if err != nil {
13		statusCode = http.StatusBadRequest
14		response.Code = statusCode
15		response.Status = err.Error()
16		return
17	}
18
19	decoder := json.NewDecoder(r.Body)
20	err = decoder.Decode(&request)
21	if err != nil {
22		statusCode = http.StatusBadRequest
23		response.Code = statusCode
24		response.Status = err.Error()
25		return
26	}
27
28	request.ID = articleID
29
30	err = d.validate.Struct(request)
31	if err != nil {
32		statusCode = http.StatusBadRequest
33		response.Code = statusCode
34		response.Status = err.Error()
35		return
36	}
37
38	res, err := d.articleUsecase.Update(r.Context(), request)
39	if err != nil {
40		statusCode = http.StatusInternalServerError
41		response.Code = statusCode
42		response.Status = err.Error()
43		return
44	}
45
46	statusCode = http.StatusOK
47	response.Data = append(response.Data, res)
48	response.Code = statusCode
49	response.Status = "OK"
50}

Pada saat update ini kita memerlukan article_id maka perlu ambil data tersebut dari parameter dengan mengambil id tersebut seperti di atas.

go
1articleIDString := params.ByName("article_id")

Kemudian ketika kita ingin mengambil body dari suatu request protokol http kita bisa menggunakan decode juga untuk dikonversikan ke dalam struct yang sudah kita buat.

go
1	decoder := json.NewDecoder(r.Body)
2	err = decoder.Decode(&request)

Kode Sumber 4.4. ## Fungsi Handler Tambah Data Artikel Pada proses handler untuk menambah data artikel dapat kita lihat seperti di bawah ini.

go
 1func (d *Pengiriman) Store(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
 2	var response models.ArticleListResponse
 3	var request models.ArticleCreateRequest
 4	var statusCode int = http.StatusBadRequest
 5
 6	defer func() {
 7		util.Response(w, response, statusCode)
 8	}()
 9
10	decoder := json.NewDecoder(r.Body)
11	err := decoder.Decode(&request)
12	if err != nil {
13		statusCode = http.StatusBadRequest
14		response.Code = statusCode
15		response.Status = err.Error()
16		return
17	}
18
19	err = d.validate.Struct(request)
20	if err != nil {
21		statusCode = http.StatusBadRequest
22		response.Code = statusCode
23		response.Status = err.Error()
24		return
25	}
26
27	res, err := d.articleUsecase.Store(r.Context(), request)
28	if err != nil {
29		statusCode = http.StatusInternalServerError
30		response.Code = statusCode
31		response.Status = err.Error()
32		return
33	}
34
35	response.Data = append(response.Data, res)
36	statusCode = http.StatusOK
37	response.Code = statusCode
38	response.Status = "OK"
39}

Kode Sumber 4.7. ## Handler Fungsi Hapus Data Artikel Pada proses usecase hapus data kita membutuhkan parameter dan body request untuk diteruskan ke usecase seperti di bawah ini.

go
 1func (d *Pengiriman) Hapus(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
 2	var response models.ArticleListResponse
 3	var statusCode int = http.StatusBadRequest
 4
 5	defer func() {
 6		util.Response(w, response, statusCode)
 7	}()
 8
 9	articleIDString := params.ByName("article_id")
10	articleID, err := strconv.ParseInt(articleIDString, 0, 64)
11	if err != nil {
12		statusCode = http.StatusBadRequest
13		response.Code = statusCode
14		response.Status = err.Error()
15		return
16	}
17
18	if articleID == 0 {
19		statusCode = http.StatusBadRequest
20		response.Code = statusCode
21		response.Status = "article_id bukan nol"
22		return
23	}
24
25	res, err := d.articleUsecase.Delete(r.Context(), articleID)
26	if err != nil {
27		statusCode = http.StatusInternalServerError
28		response.Code = statusCode
29		response.Status = err.Error()
30		return
31	}
32
33	if !res {
34		statusCode = http.StatusInternalServerError
35		response.Code = statusCode
36		response.Status = errors.New("error tidak diketahui").Error()
37		return
38	}
39
40	statusCode = http.StatusOK
41	response.Code = statusCode
42	response.Status = "OK"
43}

Related Articles

💬 Comments