diff --git a/.gitignore b/.gitignore index 993df3b..8a52e8a 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,10 @@ # Test binary, built with `go test -c` *.test -gen +bin +**/cmd +**/gen +api-cli # Output of the go coverage tool, specifically when used with LiteIDE *.out diff --git a/design/design.go b/design/design.go index 3195981..9b9a6de 100644 --- a/design/design.go +++ b/design/design.go @@ -4,20 +4,7 @@ import ( . "goa.design/goa/v3/dsl" ) -var _ = API("api", func() { - Title("API Service") - Description("An HTTP/JSON front service which provides an API to manipulate the characters, their inventories, and the items that exist") - Server("api", func() { - Host("localhost", func() { - URI("http://localhost:8000") - URI("grpc://localhost:8080") - }) - }) -}) - -var empty = Type("empty") - -var item = Type("item", func() { +var Item = Type("item", func() { Field(1, "id", Int) Field(2, "name", String) Field(3, "description", String) @@ -26,228 +13,10 @@ var item = Type("item", func() { Required("name", "description", "multiplier", "type") }) -var character = Type("character", func() { +var Character = Type("character", func() { Field(1, "id", Int) Field(2, "name", String) Field(3, "description", String) Field(4, "class", String) Required("name", "description", "class") -}) - -var _ = Service("item", func() { - Description("A GRPC back service that handles CRUD operations for the items that exist and their attributes") - - Method("getItem", func() { - Payload(Int) - Result(item) - Error("NotFound") - - HTTP(func() { - GET("/item/{id}") - Response(StatusOK) - Response(StatusBadRequest) - Response(StatusNotFound) - }) - - GRPC(func() { - Response(CodeOK) - }) - }) - - // Method("listItems", func() { - // }) - - Method("createItem", func() { - Payload(item) - Result(item) - Error("BadRequest") - - HTTP(func() { - POST("/item") - Body(item) - Response(StatusOK) - Response(StatusBadRequest) - }) - - GRPC(func() { - Response(CodeOK) - }) - }) - - Method("updateItem", func() { - Payload(item) - Result(item) - Error("NotFound") - Error("BadRequest") - - HTTP(func() { - PUT("/item/{id}") - Body(item) - Response(StatusOK) - Response(StatusBadRequest) - Response(StatusNotFound) - }) - - GRPC(func() { - Response(CodeOK) - }) - }) - - Method("deleteItem", func() { - Payload(Int) - Result(empty) - Error("NotFound") - Error("BadRequest") - - HTTP(func() { - POST("/item/{id}") - Response(StatusOK) - Response(StatusBadRequest) - Response(StatusNotFound) - }) - - GRPC(func() { - Response(CodeOK) - Response("NotFound", CodeNotFound) - Response("BadRequest", CodeInvalidArgument) - }) - }) - - Files("/openapi.json", "./gen/http/openapi.json") -}) - -var _ = Service("character", func() { - Description("A GRPC back service that handles CRUD operations for the characters and their attributes") - - Method("getCharacter", func() { - Payload(Int) - Result(character) - Error("NotFound") - Error("BadRequest") - - HTTP(func() { - GET("/character/{id}") - Response(StatusOK) - Response(StatusBadRequest) - Response(StatusNotFound) - }) - - GRPC(func() { - Response(CodeOK) - Response("NotFound", CodeNotFound) - Response("BadRequest", CodeInvalidArgument) - }) - }) - - // Method("listCharacters", func() { - // }) - - Method("createCharacter", func() { - Payload(character) - Result(character) - Error("BadRequest") - Error("NotFound") - - HTTP(func() { - POST("/character") - Body(character) - Response(StatusBadRequest) - Response(StatusOK) - Response(StatusInternalServerError) - }) - - GRPC(func() { - Response(CodeOK) - Response("NotFound", CodeNotFound) - Response("BadRequest", CodeInvalidArgument) - }) - }) - - Method("updateCharacter", func() { - Payload(character) - Result(character) - Error("NotFound") - Error("BadRequest") - - HTTP(func() { - PUT("/character/{id}") - Body(character) - Response(StatusOK) - Response(StatusBadRequest) - Response(StatusNotFound) - }) - - GRPC(func() { - Response(CodeOK) - Response("NotFound", CodeNotFound) - Response("BadRequest", CodeInvalidArgument) - }) - }) - - Method("deleteCharacter", func() { - Payload(Int) - Result(empty) - Error("NotFound") - Error("BadRequest") - - HTTP(func() { - POST("/character/{id}") - Response(StatusOK) - Response(StatusBadRequest) - Response(StatusNotFound) - }) - - GRPC(func() { - Response(CodeOK) - Response("NotFound", CodeNotFound) - Response("BadRequest", CodeInvalidArgument) - }) - }) - - Files("/openapi.json", "./gen/http/openapi.json") -}) - -var _ = Service("inventory", func() { - Description("A GRPC back service that handles CRUD operations for the characters’ inventories") - - // Method("listItems", func() { - // }) - - Method("addItem", func() { - Payload(Int) - Result(empty) - Error("NotFound") - Error("BadRequest") - - HTTP(func() { - POST("/inventory/{characterId}") - Response(StatusOK) - Response(StatusBadRequest) - }) - - GRPC(func() { - Response(CodeOK) - }) - }) - - Method("removeItem", func() { - Payload(Int) - Result(empty) - Error("NotFound") - Error("BadRequest") - - HTTP(func() { - PUT("/inventory/{characterId}") - Response(StatusOK) - Response(StatusBadRequest) - }) - - GRPC(func() { - Response(CodeOK) - Response("NotFound", CodeNotFound) - Response("BadRequest", CodeInvalidArgument) - }) - }) - - Files("/openapi.json", "./gen/http/openapi.json") }) \ No newline at end of file diff --git a/go.mod b/go.mod index 220a267..596275d 100644 --- a/go.mod +++ b/go.mod @@ -2,17 +2,27 @@ module crossnokaye-interview-assignment go 1.20 -require goa.design/goa/v3 v3.12.3 +require ( + goa.design/goa/v3 v3.12.3 + google.golang.org/grpc v1.56.2 + google.golang.org/protobuf v1.31.0 +) require ( github.com/dimfeld/httppath v0.0.0-20170720192232-ee938bf73598 // indirect + github.com/dimfeld/httptreemux/v5 v5.5.0 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/websocket v1.5.0 // indirect github.com/manveru/faker v0.0.0-20171103152722-9fbc68a78c4d // indirect github.com/sergi/go-diff v1.3.1 // indirect github.com/zach-klippenstein/goregen v0.0.0-20160303162051-795b5e3961ea // indirect golang.org/x/mod v0.12.0 // indirect + golang.org/x/net v0.12.0 // indirect golang.org/x/sys v0.10.0 // indirect golang.org/x/text v0.11.0 // indirect golang.org/x/tools v0.11.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230629202037-9506855d4529 // indirect + google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index d16147e..6093981 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,16 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dimfeld/httppath v0.0.0-20170720192232-ee938bf73598 h1:MGKhKyiYrvMDZsmLR/+RGffQSXwEkXgfLSA08qDn9AI= github.com/dimfeld/httppath v0.0.0-20170720192232-ee938bf73598/go.mod h1:0FpDmbrt36utu8jEmeU05dPC9AB5tsLYVVi+ZHfyuwI= +github.com/dimfeld/httptreemux/v5 v5.5.0 h1:p8jkiMrCuZ0CmhwYLcbNbl7DDo21fozhKHQ2PccwOFQ= +github.com/dimfeld/httptreemux/v5 v5.5.0/go.mod h1:QeEylH57C0v3VO0tkKraVz9oD3Uu93CKPnTLbsidvSw= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -20,12 +28,25 @@ goa.design/goa/v3 v3.12.3 h1:LHQDUp7t67Ml8pyQc1ywSa14eQ3JaTUBESMgOKF19bI= goa.design/goa/v3 v3.12.3/go.mod h1:y78cWNxip293j/ut0fvu8FH+s61ojHKyLbTQumk+BB4= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8= golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230629202037-9506855d4529 h1:DEH99RbiLZhMxrpEJCZ0A+wdTe0EOgou/poSLx9vWf4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230629202037-9506855d4529/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/grpc v1.56.2 h1:fVRFRnXvU+x6C4IlHZewvJOVHoOv1TUuQyoRsYnB4bI= +google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 h1:rNBFJjBCOgVr9pWD7rs/knKL4FRTKgpZmsRfV214zcA= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/scripts/build b/scripts/build new file mode 100755 index 0000000..f32ede9 --- /dev/null +++ b/scripts/build @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +set -e + +GIT_ROOT=$(git rev-parse --show-toplevel) +GIT_COMMIT=$(git rev-list -1 HEAD) +pushd ${GIT_ROOT} + +echo "Rebuilding services..." + +mkdir -p bin + +for svc in front character item inventory; do + go build -o bin/${svc} crossnokaye-interview-assignment/services/${svc}/cmd/${svc} +done + +popd \ No newline at end of file diff --git a/scripts/clean b/scripts/clean new file mode 100755 index 0000000..3bab387 --- /dev/null +++ b/scripts/clean @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +set -e + +GIT_ROOT=$(git rev-parse --show-toplevel) +GIT_COMMIT=$(git rev-list -1 HEAD) +pushd ${GIT_ROOT} + +echo "Rebuilding services..." + +mkdir -p bin + +for svc in front character item inventory; do + rm -rf services/${svc}/gen services/${svc}/cmd services/${svc}/gen services/${svc}/*.go +done + +popd \ No newline at end of file diff --git a/scripts/example b/scripts/example new file mode 100755 index 0000000..a89dc3f --- /dev/null +++ b/scripts/example @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +set -e + +GIT_ROOT=$(git rev-parse --show-toplevel) +GIT_COMMIT=$(git rev-list -1 HEAD) +pushd ${GIT_ROOT} + +echo "Rebuilding services..." + +mkdir -p bin + +for svc in front character item inventory; do + goa example crossnokaye-interview-assignment/services/${svc}/design -o services/${svc} +done + +popd \ No newline at end of file diff --git a/services/character/character.go b/services/character/character.go new file mode 100644 index 0000000..1163a74 --- /dev/null +++ b/services/character/character.go @@ -0,0 +1,45 @@ +package characterapi + +import ( + "context" + character "crossnokaye-interview-assignment/services/character/gen/character" + "log" +) + +// character service example implementation. +// The example methods log the requests and return zero values. +type charactersrvc struct { + logger *log.Logger +} + +// NewCharacter returns the character service implementation. +func NewCharacter(logger *log.Logger) character.Service { + return &charactersrvc{logger} +} + +// GetCharacter implements getCharacter. +func (s *charactersrvc) GetCharacter(ctx context.Context, p int) (res *character.Character, err error) { + res = &character.Character{} + s.logger.Print("character.getCharacter") + return +} + +// CreateCharacter implements createCharacter. +func (s *charactersrvc) CreateCharacter(ctx context.Context, p *character.Character) (res *character.Character, err error) { + res = &character.Character{} + s.logger.Print("character.createCharacter") + return +} + +// UpdateCharacter implements updateCharacter. +func (s *charactersrvc) UpdateCharacter(ctx context.Context, p *character.Character) (res *character.Character, err error) { + res = &character.Character{} + s.logger.Print("character.updateCharacter") + return +} + +// DeleteCharacter implements deleteCharacter. +func (s *charactersrvc) DeleteCharacter(ctx context.Context, p int) (err error) { + s.logger.Print("character.deleteCharacter") + return +} diff --git a/services/character/design/design.go b/services/character/design/design.go new file mode 100644 index 0000000..33fa0dc --- /dev/null +++ b/services/character/design/design.go @@ -0,0 +1,75 @@ +package design + +import ( + . "crossnokaye-interview-assignment/design" + + . "goa.design/goa/v3/dsl" +) + +var _ = API("character", func() { + Title("Character Srvice") + Server("character", func() { + Host("localhost", func() { + URI("grpc://localhost:8083") + }) + }) +}) + +var _ = Service("character", func() { + Description("A GRPC back service that handles CRUD operations for the characters and their attributes") + + Method("getCharacter", func() { + Payload(Int) + Result(Character) + Error("NotFound") + Error("BadRequest") + + GRPC(func() { + Response(CodeOK) + Response("NotFound", CodeNotFound) + Response("BadRequest", CodeInvalidArgument) + }) + }) + + // Method("listCharacters", func() { + // }) + + Method("createCharacter", func() { + Payload(Character) + Result(Character) + Error("BadRequest") + Error("NotFound") + + GRPC(func() { + Response(CodeOK) + Response("NotFound", CodeNotFound) + Response("BadRequest", CodeInvalidArgument) + }) + }) + + Method("updateCharacter", func() { + Payload(Character) + Result(Character) + Error("NotFound") + Error("BadRequest") + + GRPC(func() { + Response(CodeOK) + Response("NotFound", CodeNotFound) + Response("BadRequest", CodeInvalidArgument) + }) + }) + + Method("deleteCharacter", func() { + Payload(Int) + Result(Empty) + Error("NotFound") + Error("BadRequest") + + GRPC(func() { + Response(CodeOK) + Response("NotFound", CodeNotFound) + Response("BadRequest", CodeInvalidArgument) + }) + }) +}) diff --git a/services/front/design/design.go b/services/front/design/design.go new file mode 100644 index 0000000..cdd0f24 --- /dev/null +++ b/services/front/design/design.go @@ -0,0 +1,220 @@ +package design + +import ( + . "crossnokaye-interview-assignment/design" + + . "goa.design/goa/v3/dsl" +) + +var _ = API("front", func() { + Title("API Front Service") + Description("An HTTP/JSON front service which provides an API to manipulate the Characters, their inventories, and the Items that exist") + Server("front", func() { + Host("localhost", func() { + URI("http://localhost:8000") + }) + }) +}) + +var _ = Service("front", func() { + Description("A GRPC back service that handles CRUD operations for the Items that exist and their attributes") + + Method("getItem", func() { + Payload(Int) + Result(Item) + Error("NotFound") + + HTTP(func() { + GET("/Item/{id}") + Response(StatusOK) + Response(StatusBadRequest) + Response(StatusNotFound) + }) + + GRPC(func() { + Response(CodeOK) + }) + }) + + // Method("listItems", func() { + // }) + + Method("createItem", func() { + Payload(Item) + Result(Item) + Error("BadRequest") + + HTTP(func() { + POST("/Item") + Body(Item) + Response(StatusOK) + Response(StatusBadRequest) + }) + + GRPC(func() { + Response(CodeOK) + }) + }) + + Method("updateItem", func() { + Payload(Item) + Result(Item) + Error("NotFound") + Error("BadRequest") + + HTTP(func() { + PUT("/Item/{id}") + Body(Item) + Response(StatusOK) + Response(StatusBadRequest) + Response(StatusNotFound) + }) + + GRPC(func() { + Response(CodeOK) + }) + }) + + Method("deleteItem", func() { + Payload(Int) + Result(Empty) + Error("NotFound") + Error("BadRequest") + + HTTP(func() { + POST("/Item/{id}") + Response(StatusOK) + Response(StatusBadRequest) + Response(StatusNotFound) + }) + + GRPC(func() { + Response(CodeOK) + Response("NotFound", CodeNotFound) + Response("BadRequest", CodeInvalidArgument) + }) + }) + + Method("getCharacter", func() { + Payload(Int) + Result(Character) + Error("NotFound") + Error("BadRequest") + + HTTP(func() { + GET("/Character/{id}") + Response(StatusOK) + Response(StatusBadRequest) + Response(StatusNotFound) + }) + + GRPC(func() { + Response(CodeOK) + Response("NotFound", CodeNotFound) + Response("BadRequest", CodeInvalidArgument) + }) + }) + + // Method("listCharacters", func() { + // }) + + Method("createCharacter", func() { + Payload(Character) + Result(Character) + Error("BadRequest") + Error("NotFound") + + HTTP(func() { + POST("/Character") + Body(Character) + Response(StatusBadRequest) + Response(StatusOK) + Response(StatusInternalServerError) + }) + + GRPC(func() { + Response(CodeOK) + Response("NotFound", CodeNotFound) + Response("BadRequest", CodeInvalidArgument) + }) + }) + + Method("updateCharacter", func() { + Payload(Character) + Result(Character) + Error("NotFound") + Error("BadRequest") + + HTTP(func() { + PUT("/Character/{id}") + Body(Character) + Response(StatusOK) + Response(StatusBadRequest) + Response(StatusNotFound) + }) + + GRPC(func() { + Response(CodeOK) + Response("NotFound", CodeNotFound) + Response("BadRequest", CodeInvalidArgument) + }) + }) + + Method("deleteCharacter", func() { + Payload(Int) + Result(Empty) + Error("NotFound") + Error("BadRequest") + + HTTP(func() { + POST("/Character/{id}") + Response(StatusOK) + Response(StatusBadRequest) + Response(StatusNotFound) + }) + + GRPC(func() { + Response(CodeOK) + Response("NotFound", CodeNotFound) + Response("BadRequest", CodeInvalidArgument) + }) + }) + + Method("addItemToInventory", func() { + Payload(Int) + Result(Empty) + Error("NotFound") + Error("BadRequest") + + HTTP(func() { + POST("/inventory/{CharacterId}") + Response(StatusOK) + Response(StatusBadRequest) + }) + + GRPC(func() { + Response(CodeOK) + }) + }) + + Method("removeItemFromInventory", func() { + Payload(Int) + Result(Empty) + Error("NotFound") + Error("BadRequest") + + HTTP(func() { + PUT("/inventory/{CharacterId}") + Response(StatusOK) + Response(StatusBadRequest) + }) + + GRPC(func() { + Response(CodeOK) + Response("NotFound", CodeNotFound) + Response("BadRequest", CodeInvalidArgument) + }) + }) + + Files("/openapi.json", "./gen/http/openapi.json") +}) diff --git a/services/front/front.go b/services/front/front.go new file mode 100644 index 0000000..e9c18f3 --- /dev/null +++ b/services/front/front.go @@ -0,0 +1,84 @@ +package frontapi + +import ( + "context" + front "crossnokaye-interview-assignment/services/front/gen/front" + "log" +) + +// front service example implementation. +// The example methods log the requests and return zero values. +type frontsrvc struct { + logger *log.Logger +} + +// NewFront returns the front service implementation. +func NewFront(logger *log.Logger) front.Service { + return &frontsrvc{logger} +} + +// GetItem implements getItem. +func (s *frontsrvc) GetItem(ctx context.Context, p int) (res *front.Item, err error) { + res = &front.Item{} + s.logger.Print("front.getItem") + return +} + +// CreateItem implements createItem. +func (s *frontsrvc) CreateItem(ctx context.Context, p *front.Item) (res *front.Item, err error) { + res = &front.Item{} + s.logger.Print("front.createItem") + return +} + +// UpdateItem implements updateItem. +func (s *frontsrvc) UpdateItem(ctx context.Context, p *front.Item) (res *front.Item, err error) { + res = &front.Item{} + s.logger.Print("front.updateItem") + return +} + +// DeleteItem implements deleteItem. +func (s *frontsrvc) DeleteItem(ctx context.Context, p int) (err error) { + s.logger.Print("front.deleteItem") + return +} + +// GetCharacter implements getCharacter. +func (s *frontsrvc) GetCharacter(ctx context.Context, p int) (res *front.Character, err error) { + res = &front.Character{} + s.logger.Print("front.getCharacter") + return +} + +// CreateCharacter implements createCharacter. +func (s *frontsrvc) CreateCharacter(ctx context.Context, p *front.Character) (res *front.Character, err error) { + res = &front.Character{} + s.logger.Print("front.createCharacter") + return +} + +// UpdateCharacter implements updateCharacter. +func (s *frontsrvc) UpdateCharacter(ctx context.Context, p *front.Character) (res *front.Character, err error) { + res = &front.Character{} + s.logger.Print("front.updateCharacter") + return +} + +// DeleteCharacter implements deleteCharacter. +func (s *frontsrvc) DeleteCharacter(ctx context.Context, p int) (err error) { + s.logger.Print("front.deleteCharacter") + return +} + +// AddItemToInventory implements addItemToInventory. +func (s *frontsrvc) AddItemToInventory(ctx context.Context, p int) (err error) { + s.logger.Print("front.addItemToInventory") + return +} + +// RemoveItemFromInventory implements removeItemFromInventory. +func (s *frontsrvc) RemoveItemFromInventory(ctx context.Context, p int) (err error) { + s.logger.Print("front.removeItemFromInventory") + return +} diff --git a/services/inventory/design/design.go b/services/inventory/design/design.go new file mode 100644 index 0000000..1d83cc6 --- /dev/null +++ b/services/inventory/design/design.go @@ -0,0 +1,44 @@ +package design + +import ( + . "goa.design/goa/v3/dsl" +) + +var _ = API("inventory", func() { + Title("Inventory Service") + Server("inventory", func() { + Host("localhost", func() { + URI("grpc://localhost:8081") + }) + }) +}) + +var _ = Service("inventory", func() { + Description("A GRPC back service that handles CRUD operations for the characters’ inventories") + // Method("listItems", func() { + // }) + + Method("addItem", func() { + Payload(Int) + Result(Empty) + Error("NotFound") + Error("BadRequest") + + GRPC(func() { + Response(CodeOK) + }) + }) + + Method("removeItem", func() { + Payload(Int) + Result(Empty) + Error("NotFound") + Error("BadRequest") + + GRPC(func() { + Response(CodeOK) + Response("NotFound", CodeNotFound) + Response("BadRequest", CodeInvalidArgument) + }) + }) +}) diff --git a/services/inventory/inventory.go b/services/inventory/inventory.go new file mode 100644 index 0000000..5ef1a54 --- /dev/null +++ b/services/inventory/inventory.go @@ -0,0 +1,30 @@ +package inventoryapi + +import ( + "context" + inventory "crossnokaye-interview-assignment/services/inventory/gen/inventory" + "log" +) + +// inventory service example implementation. +// The example methods log the requests and return zero values. +type inventorysrvc struct { + logger *log.Logger +} + +// NewInventory returns the inventory service implementation. +func NewInventory(logger *log.Logger) inventory.Service { + return &inventorysrvc{logger} +} + +// AddItem implements addItem. +func (s *inventorysrvc) AddItem(ctx context.Context, p int) (err error) { + s.logger.Print("inventory.addItem") + return +} + +// RemoveItem implements removeItem. +func (s *inventorysrvc) RemoveItem(ctx context.Context, p int) (err error) { + s.logger.Print("inventory.removeItem") + return +} diff --git a/services/item/design/design.go b/services/item/design/design.go new file mode 100644 index 0000000..60a9b29 --- /dev/null +++ b/services/item/design/design.go @@ -0,0 +1,67 @@ +package design + +import ( + . "crossnokaye-interview-assignment/design" + + . "goa.design/goa/v3/dsl" +) + +var _ = API("item", func() { + Title("Item Service") + Server("item", func() { + Host("localhost", func() { + URI("grpc://localhost:8082") + }) + }) +}) + +var _ = Service("item", func() { + Description("A GRPC back service that handles CRUD operations for the items that exist and their attributes") + + Method("getItem", func() { + Payload(Int) + Result(Item) + Error("NotFound") + + GRPC(func() { + Response(CodeOK) + }) + }) + + // Method("listItems", func() { + // }) + + Method("createItem", func() { + Payload(Item) + Result(Item) + Error("BadRequest") + + GRPC(func() { + Response(CodeOK) + }) + }) + + Method("updateItem", func() { + Payload(Item) + Result(Item) + Error("NotFound") + Error("BadRequest") + + GRPC(func() { + Response(CodeOK) + }) + }) + + Method("deleteItem", func() { + Payload(Int) + Result(Empty) + Error("NotFound") + Error("BadRequest") + + GRPC(func() { + Response(CodeOK) + Response("NotFound", CodeNotFound) + Response("BadRequest", CodeInvalidArgument) + }) + }) +}) \ No newline at end of file diff --git a/services/item/item.go b/services/item/item.go new file mode 100644 index 0000000..d1178b5 --- /dev/null +++ b/services/item/item.go @@ -0,0 +1,45 @@ +package itemapi + +import ( + "context" + item "crossnokaye-interview-assignment/services/item/gen/item" + "log" +) + +// item service example implementation. +// The example methods log the requests and return zero values. +type itemsrvc struct { + logger *log.Logger +} + +// NewItem returns the item service implementation. +func NewItem(logger *log.Logger) item.Service { + return &itemsrvc{logger} +} + +// GetItem implements getItem. +func (s *itemsrvc) GetItem(ctx context.Context, p int) (res *item.Item, err error) { + res = &item.Item{} + s.logger.Print("item.getItem") + return +} + +// CreateItem implements createItem. +func (s *itemsrvc) CreateItem(ctx context.Context, p *item.Item) (res *item.Item, err error) { + res = &item.Item{} + s.logger.Print("item.createItem") + return +} + +// UpdateItem implements updateItem. +func (s *itemsrvc) UpdateItem(ctx context.Context, p *item.Item) (res *item.Item, err error) { + res = &item.Item{} + s.logger.Print("item.updateItem") + return +} + +// DeleteItem implements deleteItem. +func (s *itemsrvc) DeleteItem(ctx context.Context, p int) (err error) { + s.logger.Print("item.deleteItem") + return +}