Skip to content

Commit c48cfb8

Browse files
committed
[add] Added storage.go abstraction layer
1 parent dc1287b commit c48cfb8

File tree

4 files changed

+51
-22
lines changed

4 files changed

+51
-22
lines changed

author.go

+2-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package main
22

3-
import "fmt"
4-
53
// The Author struct represents the data in the JSON/JSONB column.
64
// We can use struct tags to control how each field is encoded.
75
type Author struct {
@@ -10,7 +8,7 @@ type Author struct {
108
About string `json:"About"`
119
}
1210

13-
func authorToHsetCmdArgs(author Author) []interface{} {
11+
func authorToKeyValueMap(author Author) []interface{} {
1412
nonNullValues := make([]interface{}, 0)
1513
if author.Name != "" {
1614
nonNullValues = append(nonNullValues, "Name", author.Name)
@@ -24,11 +22,7 @@ func authorToHsetCmdArgs(author Author) []interface{} {
2422
return nonNullValues
2523
}
2624

27-
func getRedisAuthorKey(authorId int) string {
28-
return fmt.Sprintf("author:%d", authorId)
29-
}
30-
31-
func UpdateAuthorFromRedisReply(author Author, redisReply map[string]string) (updatedAuthor Author, err error) {
25+
func UpdateAuthorFromMapState(author Author, redisReply map[string]string) (updatedAuthor Author, err error) {
3226
updatedAuthor = author
3327
if name, ok := redisReply["Name"]; ok {
3428
updatedAuthor.Name = name

main.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ type server struct {
2828

2929
func initTracer(serviceName string, jaegerAgentEndpoint string) {
3030

31-
// Create and install Jaeger export pipeline
31+
// Spans are created by tracers, which can be acquired from a Tracer Provider.
32+
// In our example we will use Jaeger as our trace provider
33+
// To do so, we will follow Jaeger godoc and leverage the NewExportPipeline() method
34+
// that sets up a complete export pipeline with the recommended setup for trace provider
3235
tp, _, err := jaeger.NewExportPipeline(
3336
jaeger.WithCollectorEndpoint(fmt.Sprintf("%s/api/traces", jaegerAgentEndpoint)),
3437
jaeger.WithProcess(jaeger.Process{
@@ -49,6 +52,7 @@ func initTracer(serviceName string, jaegerAgentEndpoint string) {
4952
// See: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#tracerprovider
5053
otel.SetTracerProvider(tp)
5154

55+
// Traces can extend beyond a single process. This requires context propagation, a mechanism where identifiers for a trace are sent to remote processes.
5256
// TextMapPropagator performs the injection and extraction of a cross-cutting concern value as string key/values
5357
// pairs into carriers that travel in-band across process boundaries.
5458
// The carrier of propagated data on both the client (injector) and server (extractor) side is usually an HTTP request.

routes.go

+8-13
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ func (server *server) routes() {
1818

1919
func getIdFromRequest(req *http.Request) (id int, err error) {
2020
vars := mux.Vars(req)
21-
fmt.Println(vars["id"])
2221
if vars["id"] != "" {
2322
id, _ = strconv.Atoi(vars["id"])
2423
} else {
@@ -45,18 +44,10 @@ func (server *server) handleAuthorPostOrPut() http.HandlerFunc {
4544
return
4645
}
4746
ctx := req.Context()
48-
nonNullValues := authorToHsetCmdArgs(author)
49-
_, err = server.client.HSet(ctx, getRedisAuthorKey(authorId), nonNullValues...).Result()
50-
if err != nil {
51-
http.Error(w, err.Error(), http.StatusBadRequest)
52-
return
53-
}
54-
redisReply, err := server.client.HGetAll(ctx, getRedisAuthorKey(authorId)).Result()
55-
if err != nil {
56-
http.Error(w, err.Error(), http.StatusBadRequest)
47+
err, replyAuthor, done := server.persistToStorageLayer(w, author, err, ctx, authorId)
48+
if done {
5749
return
5850
}
59-
replyAuthor, _ := UpdateAuthorFromRedisReply(author, redisReply)
6051
encodedAuthor, err := json.Marshal(replyAuthor)
6152
if err != nil {
6253
http.Error(w, err.Error(), http.StatusBadRequest)
@@ -74,12 +65,16 @@ func (server *server) handleAuthorGet() http.HandlerFunc {
7465
return
7566
}
7667
ctx := req.Context()
77-
redisReply, err := server.client.HGetAll(ctx, getRedisAuthorKey(authorId)).Result()
68+
found, storageReplyMap := server.retrieveFromStorageLayer(err, ctx, authorId)
7869
if err != nil {
7970
http.Error(w, err.Error(), http.StatusBadRequest)
8071
return
8172
}
82-
replyAuthor, _ := UpdateAuthorFromRedisReply(Author{}, redisReply)
73+
if !found {
74+
http.Error(w, fmt.Sprintf("The resource Author with id %d does not exist", authorId), http.StatusNotFound)
75+
return
76+
}
77+
replyAuthor, _ := UpdateAuthorFromMapState(Author{}, storageReplyMap)
8378
encodedAuthor, err := json.Marshal(replyAuthor)
8479
if err != nil {
8580
http.Error(w, err.Error(), http.StatusBadRequest)

storage.go

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"net/http"
7+
)
8+
9+
func getRedisAuthorKey(authorId int) string {
10+
return fmt.Sprintf("author:%d", authorId)
11+
}
12+
13+
func (server *server) persistToStorageLayer(w http.ResponseWriter, author Author, err error, ctx context.Context, authorId int) (error, Author, bool) {
14+
nonNullValues := authorToKeyValueMap(author)
15+
_, err = server.client.HSet(ctx, getRedisAuthorKey(authorId), nonNullValues...).Result()
16+
if err != nil {
17+
http.Error(w, err.Error(), http.StatusBadRequest)
18+
return nil, Author{}, true
19+
}
20+
redisReply, err := server.client.HGetAll(ctx, getRedisAuthorKey(authorId)).Result()
21+
if err != nil {
22+
http.Error(w, err.Error(), http.StatusBadRequest)
23+
return nil, Author{}, true
24+
}
25+
replyAuthor, _ := UpdateAuthorFromMapState(author, redisReply)
26+
return err, replyAuthor, false
27+
}
28+
29+
func (server *server) retrieveFromStorageLayer(err error, ctx context.Context, authorId int) (found bool, storageReplyMap map[string]string) {
30+
storageReplyMap, err = server.client.HGetAll(ctx, getRedisAuthorKey(authorId)).Result()
31+
found = true
32+
if len(storageReplyMap) == 0 {
33+
found = false
34+
}
35+
return
36+
}

0 commit comments

Comments
 (0)