Skip to content

Commit b3d01c0

Browse files
committed
feat: add character retrieval endpoint and associated query logic
1 parent 86a4da4 commit b3d01c0

6 files changed

Lines changed: 108 additions & 4 deletions

File tree

api/bruno/character.bru

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
meta {
2+
name: character
3+
type: http
4+
seq: 4
5+
}
6+
7+
get {
8+
url: {{BASE_URL}}/character/qyeufszVydeucS2CRGfKjC
9+
body: none
10+
auth: inherit
11+
}
12+
13+
params:query {
14+
~limit: 10
15+
~skip: 0
16+
}
17+
18+
body:json {
19+
{
20+
"limit": 10,
21+
"skip": 0
22+
}
23+
}

cmd/api/charactersapi/character.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package charactersapi
2+
3+
import (
4+
"net/http"
5+
6+
"github.com/UltimateForm/gopen-api/internal/core"
7+
"github.com/UltimateForm/gopen-api/internal/repository/charrep"
8+
"github.com/go-chi/chi/v5"
9+
)
10+
11+
func HandleGetCharacter(res http.ResponseWriter, req *http.Request) {
12+
id := chi.URLParam(req, "id")
13+
if id == "" {
14+
core.RespondError(res, req, core.BadRequest("id in path is required"))
15+
return
16+
}
17+
character, err := charrep.ReadOneCharacter(req.Context(), id)
18+
if err != nil {
19+
core.RespondError(res, req, err)
20+
return
21+
}
22+
var char Character = Character{
23+
Id: character.Id,
24+
Name: character.Name,
25+
Description: character.Description,
26+
Debut: character.Debut,
27+
}
28+
core.RespondOk(res, char)
29+
}

cmd/api/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ func Start() http.Handler {
1919
router.Route("/characters", func(r chi.Router) {
2020
r.Use(core.AuthMiddleware)
2121
r.Get("/", charactersapi.HandleGetCharacters)
22+
r.Get("/{id}", charactersapi.HandleGetCharacter)
2223
})
2324
log.Println("ROUTER CREATED")
2425
return router

internal/repository/authrep/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
)
1010

1111
func txUsrExistsAtomically(ctx context.Context, user User) neo4j.ManagedTransactionWorkT[bool] {
12-
query := repository.NewQuery(
12+
query := repository.NewQueryWithParams(
1313
user,
1414
`
1515
MATCH (u:User {email:$email, password:$password})

internal/repository/charrep/main.go

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,57 @@ package charrep
22

33
import (
44
"context"
5+
"errors"
56
"log"
67

78
"github.com/UltimateForm/gopen-api/internal/repository"
89
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
910
)
1011

12+
func txReadOneCharacter(ctx context.Context, id string) neo4j.ManagedTransactionWorkT[Character] {
13+
query := repository.NewQuery(map[string]any{"id": id},
14+
`
15+
MATCH (character:Character {id: $id})
16+
RETURN character
17+
`)
18+
return func(tx neo4j.ManagedTransaction) (Character, error) {
19+
res, err := query.Execute(tx, ctx)
20+
if err != nil {
21+
return Character{}, err
22+
}
23+
24+
record, singleErr := res.Single(ctx)
25+
if singleErr != nil {
26+
return Character{}, singleErr
27+
}
28+
29+
rowMap, rowMapOk := record.AsMap()["character"]
30+
rowCharacter, rowCharacterOk := rowMap.(neo4j.Node)
31+
if !rowMapOk || !rowCharacterOk {
32+
return Character{}, errors.New("bad row from db")
33+
}
34+
35+
propsMap := rowCharacter.GetProperties()
36+
name := propsMap["name"]
37+
id := propsMap["id"]
38+
description := propsMap["description"]
39+
debut := propsMap["debut"]
40+
nameStr := name.(string)
41+
idStr := id.(string)
42+
debutNum := int(debut.(float64))
43+
descrStr := description.(string)
44+
45+
return Character{
46+
Name: nameStr,
47+
Id: idStr,
48+
Debut: debutNum,
49+
Description: descrStr,
50+
}, nil
51+
}
52+
}
53+
1154
func txReadCharacters(ctx context.Context, offset Offset) neo4j.ManagedTransactionWorkT[[]Character] {
12-
query := repository.NewQuery(offset,
55+
query := repository.NewQueryWithParams(offset,
1356
`
1457
MATCH (character:Character)
1558
RETURN character
@@ -61,3 +104,7 @@ LIMIT $limit
61104
func ReadCharacters(ctx context.Context, offset Offset) ([]Character, error) {
62105
return repository.ExecuteReadWithDriver(ctx, txReadCharacters(ctx, offset))
63106
}
107+
108+
func ReadOneCharacter(ctx context.Context, id string) (Character, error) {
109+
return repository.ExecuteReadWithDriver(ctx, txReadOneCharacter(ctx, id))
110+
}

internal/repository/main.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,15 @@ func ExecuteReadWithDriver[T any](ctx context.Context, tx neo4j.ManagedTransacti
1616
})
1717
}
1818

19-
func NewQuery(data IQueryParams, query string) QueryRunner {
19+
func NewQuery(data map[string]any, query string) QueryRunner {
2020
return func(tx neo4j.ManagedTransaction, ctx context.Context) (neo4j.ResultWithContext, error) {
2121
return tx.Run(
2222
ctx,
2323
query,
24-
data.ToParams())
24+
data)
2525
}
2626
}
27+
28+
func NewQueryWithParams(data IQueryParams, query string) QueryRunner {
29+
return NewQuery(data.ToParams(), query)
30+
}

0 commit comments

Comments
 (0)