add protobuf contract back to front; make pokemon structs internal
This commit is contained in:
parent
315527ee72
commit
fd10dbbd13
|
@ -1,2 +1,3 @@
|
|||
.idea/
|
||||
pokedex.db
|
||||
pokedex
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
.PHONY : build
|
||||
.DEFAULT_GOAL := build
|
||||
|
||||
build:
|
||||
rm -rf pokedex*
|
||||
swag init
|
||||
protoc -I=./ --go_out=../ ./pokemon/pokemon.proto
|
||||
go build
|
||||
|
||||
|
||||
|
|
@ -7,7 +7,12 @@ A simple Go-powered REST API kata.
|
|||
|
||||
- KISS: Use built-in `http` package. https://gin-gonic.com/ looks cooler but also adds dozens of dependencies 😮 No need for a "fully-featured" web framework.
|
||||
|
||||
## Protobuf
|
||||
|
||||
- JSON mapping: https://protobuf.dev/programming-guides/proto3/#json
|
||||
|
||||
## Swagger
|
||||
|
||||
- Exposed at `http://localhost:8080/docs`
|
||||
- Regenerate with `swag init`, see https://github.com/swaggo/http-swagger
|
||||
- Annotation format: see https://github.com/swaggo/swag
|
32
docs/docs.go
32
docs/docs.go
|
@ -27,13 +27,13 @@ const docTemplate = `{
|
|||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"summary": "get all Pokemon",
|
||||
"summary": "get all pokemon",
|
||||
"operationId": "get-all-pokemon",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/pokemon.Pokemon"
|
||||
"$ref": "#/definitions/pb.Pokemons"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,13 +44,13 @@ const docTemplate = `{
|
|||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"summary": "Find a specific Pokemon by name",
|
||||
"summary": "Find a specific pokemon by name",
|
||||
"operationId": "get-specific-pokemon",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/pokemon.Pokemon"
|
||||
"$ref": "#/definitions/pb.Pokemons"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
|
@ -64,34 +64,27 @@ const docTemplate = `{
|
|||
}
|
||||
},
|
||||
"definitions": {
|
||||
"pokemon.Move": {
|
||||
"pb.Move": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"pokemonID": {
|
||||
"description": "implicit; see https://gorm.io/docs/has_many.html",
|
||||
"type": "integer"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pokemon.Pokemon": {
|
||||
"pb.Pokemon": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"height": {
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"moves": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/pokemon.Move"
|
||||
"$ref": "#/definitions/pb.Move"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
|
@ -101,6 +94,17 @@ const docTemplate = `{
|
|||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pb.Pokemons": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"entries": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/pb.Pokemon"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
|
|
@ -21,13 +21,13 @@
|
|||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"summary": "get all Pokemon",
|
||||
"summary": "get all pokemon",
|
||||
"operationId": "get-all-pokemon",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/pokemon.Pokemon"
|
||||
"$ref": "#/definitions/pb.Pokemons"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,13 +38,13 @@
|
|||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"summary": "Find a specific Pokemon by name",
|
||||
"summary": "Find a specific pokemon by name",
|
||||
"operationId": "get-specific-pokemon",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/pokemon.Pokemon"
|
||||
"$ref": "#/definitions/pb.Pokemons"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
|
@ -58,34 +58,27 @@
|
|||
}
|
||||
},
|
||||
"definitions": {
|
||||
"pokemon.Move": {
|
||||
"pb.Move": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"pokemonID": {
|
||||
"description": "implicit; see https://gorm.io/docs/has_many.html",
|
||||
"type": "integer"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pokemon.Pokemon": {
|
||||
"pb.Pokemon": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"height": {
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"moves": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/pokemon.Move"
|
||||
"$ref": "#/definitions/pb.Move"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
|
@ -95,6 +88,17 @@
|
|||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pb.Pokemons": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"entries": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/pb.Pokemon"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,30 +1,32 @@
|
|||
basePath: /
|
||||
definitions:
|
||||
pokemon.Move:
|
||||
pb.Move:
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
pokemonID:
|
||||
description: implicit; see https://gorm.io/docs/has_many.html
|
||||
type: integer
|
||||
url:
|
||||
type: string
|
||||
type: object
|
||||
pokemon.Pokemon:
|
||||
pb.Pokemon:
|
||||
properties:
|
||||
height:
|
||||
type: integer
|
||||
id:
|
||||
type: integer
|
||||
moves:
|
||||
items:
|
||||
$ref: '#/definitions/pokemon.Move'
|
||||
$ref: '#/definitions/pb.Move'
|
||||
type: array
|
||||
name:
|
||||
type: string
|
||||
weight:
|
||||
type: integer
|
||||
type: object
|
||||
pb.Pokemons:
|
||||
properties:
|
||||
entries:
|
||||
items:
|
||||
$ref: '#/definitions/pb.Pokemon'
|
||||
type: array
|
||||
type: object
|
||||
host: localhost:8080
|
||||
info:
|
||||
contact:
|
||||
|
@ -46,8 +48,8 @@ paths:
|
|||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/pokemon.Pokemon'
|
||||
summary: get all Pokemon
|
||||
$ref: '#/definitions/pb.Pokemons'
|
||||
summary: get all pokemon
|
||||
/pokemon/{name}:
|
||||
get:
|
||||
operationId: get-specific-pokemon
|
||||
|
@ -57,10 +59,10 @@ paths:
|
|||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/pokemon.Pokemon'
|
||||
$ref: '#/definitions/pb.Pokemons'
|
||||
"500":
|
||||
description: error
|
||||
schema:
|
||||
type: string
|
||||
summary: Find a specific Pokemon by name
|
||||
summary: Find a specific pokemon by name
|
||||
swagger: "2.0"
|
||||
|
|
7
go.mod
7
go.mod
|
@ -3,6 +3,9 @@ module pokedex
|
|||
go 1.22
|
||||
|
||||
require (
|
||||
github.com/swaggo/http-swagger v1.3.4
|
||||
github.com/swaggo/swag v1.16.3
|
||||
google.golang.org/protobuf v1.33.0
|
||||
gorm.io/driver/sqlite v1.5.5
|
||||
gorm.io/gorm v1.25.9
|
||||
)
|
||||
|
@ -19,11 +22,7 @@ require (
|
|||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.22 // indirect
|
||||
github.com/swaggo/files v1.0.1 // indirect
|
||||
github.com/swaggo/http-swagger v1.3.4 // indirect
|
||||
github.com/swaggo/swag v1.16.3 // indirect
|
||||
golang.org/x/net v0.24.0 // indirect
|
||||
golang.org/x/sys v0.19.0 // indirect
|
||||
golang.org/x/tools v0.20.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
|
25
go.sum
25
go.sum
|
@ -1,5 +1,6 @@
|
|||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
|
||||
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
|
||||
|
@ -9,18 +10,28 @@ github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9Z
|
|||
github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=
|
||||
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
||||
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=
|
||||
github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=
|
||||
github.com/swaggo/http-swagger v1.3.4 h1:q7t/XLx0n15H1Q9/tk3Y9L4n210XzJF5WtnDX64a5ww=
|
||||
|
@ -31,6 +42,8 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t
|
|||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
|
@ -39,14 +52,14 @@ golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
|||
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
|
@ -60,9 +73,13 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc
|
|||
golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY=
|
||||
golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/sqlite v1.5.5 h1:7MDMtUZhV065SilG62E0MquljeArQZNfJnjd9i9gx3E=
|
||||
|
|
|
@ -0,0 +1,306 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.33.0
|
||||
// protoc v5.26.1
|
||||
// source: pokemon/pokemon.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type Move struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Move) Reset() {
|
||||
*x = Move{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_pokemon_pokemon_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Move) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Move) ProtoMessage() {}
|
||||
|
||||
func (x *Move) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_pokemon_pokemon_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Move.ProtoReflect.Descriptor instead.
|
||||
func (*Move) Descriptor() ([]byte, []int) {
|
||||
return file_pokemon_pokemon_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Move) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Move) GetUrl() string {
|
||||
if x != nil {
|
||||
return x.Url
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Pokemons struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Entries []*Pokemon `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Pokemons) Reset() {
|
||||
*x = Pokemons{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_pokemon_pokemon_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Pokemons) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Pokemons) ProtoMessage() {}
|
||||
|
||||
func (x *Pokemons) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_pokemon_pokemon_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Pokemons.ProtoReflect.Descriptor instead.
|
||||
func (*Pokemons) Descriptor() ([]byte, []int) {
|
||||
return file_pokemon_pokemon_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *Pokemons) GetEntries() []*Pokemon {
|
||||
if x != nil {
|
||||
return x.Entries
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Pokemon struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Height int32 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"`
|
||||
Weight int32 `protobuf:"varint,3,opt,name=weight,proto3" json:"weight,omitempty"`
|
||||
Moves []*Move `protobuf:"bytes,4,rep,name=moves,proto3" json:"moves,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Pokemon) Reset() {
|
||||
*x = Pokemon{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_pokemon_pokemon_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Pokemon) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Pokemon) ProtoMessage() {}
|
||||
|
||||
func (x *Pokemon) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_pokemon_pokemon_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Pokemon.ProtoReflect.Descriptor instead.
|
||||
func (*Pokemon) Descriptor() ([]byte, []int) {
|
||||
return file_pokemon_pokemon_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *Pokemon) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Pokemon) GetHeight() int32 {
|
||||
if x != nil {
|
||||
return x.Height
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Pokemon) GetWeight() int32 {
|
||||
if x != nil {
|
||||
return x.Weight
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Pokemon) GetMoves() []*Move {
|
||||
if x != nil {
|
||||
return x.Moves
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_pokemon_pokemon_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_pokemon_pokemon_proto_rawDesc = []byte{
|
||||
0x0a, 0x15, 0x70, 0x6f, 0x6b, 0x65, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x6f, 0x6b, 0x65, 0x6d, 0x6f,
|
||||
0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x2c, 0x0a, 0x04, 0x4d, 0x6f, 0x76, 0x65, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
|
||||
0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x2e, 0x0a, 0x08, 0x50, 0x6f, 0x6b, 0x65, 0x6d, 0x6f, 0x6e,
|
||||
0x73, 0x12, 0x22, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x08, 0x2e, 0x50, 0x6f, 0x6b, 0x65, 0x6d, 0x6f, 0x6e, 0x52, 0x07, 0x65, 0x6e,
|
||||
0x74, 0x72, 0x69, 0x65, 0x73, 0x22, 0x6a, 0x0a, 0x07, 0x50, 0x6f, 0x6b, 0x65, 0x6d, 0x6f, 0x6e,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
|
||||
0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x16, 0x0a, 0x06,
|
||||
0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x77, 0x65,
|
||||
0x69, 0x67, 0x68, 0x74, 0x12, 0x1b, 0x0a, 0x05, 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x18, 0x04, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x05, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x52, 0x05, 0x6d, 0x6f, 0x76, 0x65,
|
||||
0x73, 0x42, 0x0c, 0x5a, 0x0a, 0x70, 0x6f, 0x6b, 0x65, 0x64, 0x65, 0x78, 0x2f, 0x70, 0x62, 0x62,
|
||||
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_pokemon_pokemon_proto_rawDescOnce sync.Once
|
||||
file_pokemon_pokemon_proto_rawDescData = file_pokemon_pokemon_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_pokemon_pokemon_proto_rawDescGZIP() []byte {
|
||||
file_pokemon_pokemon_proto_rawDescOnce.Do(func() {
|
||||
file_pokemon_pokemon_proto_rawDescData = protoimpl.X.CompressGZIP(file_pokemon_pokemon_proto_rawDescData)
|
||||
})
|
||||
return file_pokemon_pokemon_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_pokemon_pokemon_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
||||
var file_pokemon_pokemon_proto_goTypes = []interface{}{
|
||||
(*Move)(nil), // 0: Move
|
||||
(*Pokemons)(nil), // 1: Pokemons
|
||||
(*Pokemon)(nil), // 2: Pokemon
|
||||
}
|
||||
var file_pokemon_pokemon_proto_depIdxs = []int32{
|
||||
2, // 0: Pokemons.entries:type_name -> Pokemon
|
||||
0, // 1: Pokemon.moves:type_name -> Move
|
||||
2, // [2:2] is the sub-list for method output_type
|
||||
2, // [2:2] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension type_name
|
||||
2, // [2:2] is the sub-list for extension extendee
|
||||
0, // [0:2] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_pokemon_pokemon_proto_init() }
|
||||
func file_pokemon_pokemon_proto_init() {
|
||||
if File_pokemon_pokemon_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_pokemon_pokemon_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Move); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_pokemon_pokemon_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Pokemons); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_pokemon_pokemon_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Pokemon); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_pokemon_pokemon_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 3,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_pokemon_pokemon_proto_goTypes,
|
||||
DependencyIndexes: file_pokemon_pokemon_proto_depIdxs,
|
||||
MessageInfos: file_pokemon_pokemon_proto_msgTypes,
|
||||
}.Build()
|
||||
File_pokemon_pokemon_proto = out.File
|
||||
file_pokemon_pokemon_proto_rawDesc = nil
|
||||
file_pokemon_pokemon_proto_goTypes = nil
|
||||
file_pokemon_pokemon_proto_depIdxs = nil
|
||||
}
|
|
@ -7,10 +7,10 @@ import (
|
|||
"pokedex/rest"
|
||||
)
|
||||
|
||||
// @Summary Find a specific Pokemon by name
|
||||
// @Summary Find a specific pokemon by name
|
||||
// @ID get-specific-pokemon
|
||||
// @Produce json
|
||||
// @Success 200 {object} Pokemon
|
||||
// @Success 200 {object} pb.Pokemons
|
||||
// @failure 500 {string} string "error"
|
||||
// @Router /pokemon/{name} [get]
|
||||
func HandleFindSingle(db *gorm.DB, rw http.ResponseWriter, req *http.Request) {
|
||||
|
@ -24,15 +24,13 @@ func HandleFindSingle(db *gorm.DB, rw http.ResponseWriter, req *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
rest.Json(rw, []Pokemon{
|
||||
pk,
|
||||
})
|
||||
rest.ProtoJson(rw, pk.ToPbWrapped())
|
||||
}
|
||||
|
||||
// @Summary get all Pokemon
|
||||
// @Summary get all pokemon
|
||||
// @ID get-all-pokemon
|
||||
// @Produce json
|
||||
// @Success 200 {object} Pokemon
|
||||
// @Success 200 {object} pb.Pokemons
|
||||
// @Router /pokemon [get]
|
||||
func HandleFindAll(db *gorm.DB, rw http.ResponseWriter, req *http.Request) {
|
||||
repo := NewRepo(db)
|
||||
|
@ -42,5 +40,5 @@ func HandleFindAll(db *gorm.DB, rw http.ResponseWriter, req *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
rest.Json(rw, pokemons)
|
||||
rest.ProtoJson(rw, ToPb(pokemons))
|
||||
}
|
||||
|
|
|
@ -1,15 +1,57 @@
|
|||
package pokemon
|
||||
|
||||
type Move struct {
|
||||
import "pokedex/pb"
|
||||
|
||||
type move struct {
|
||||
Name string
|
||||
Url string
|
||||
PokemonID uint // implicit; see https://gorm.io/docs/has_many.html
|
||||
}
|
||||
|
||||
type Pokemon struct {
|
||||
func (m move) ToPb() *pb.Move {
|
||||
return &pb.Move{
|
||||
Name: m.Name,
|
||||
Url: m.Url,
|
||||
}
|
||||
}
|
||||
|
||||
type pokemon struct {
|
||||
Id int
|
||||
Name string
|
||||
Height int
|
||||
Weight int
|
||||
Moves []Move
|
||||
Moves []move
|
||||
}
|
||||
|
||||
func ToPb(p []pokemon) *pb.Pokemons {
|
||||
pbs := make([]*pb.Pokemon, len(p))
|
||||
for i, m := range p {
|
||||
pbs[i] = m.ToPb()
|
||||
}
|
||||
|
||||
return &pb.Pokemons{
|
||||
Entries: pbs,
|
||||
}
|
||||
}
|
||||
|
||||
func (p pokemon) ToPbWrapped() *pb.Pokemons {
|
||||
pbs := make([]*pb.Pokemon, 1)
|
||||
pbs = append(pbs, p.ToPb())
|
||||
return &pb.Pokemons{
|
||||
Entries: pbs,
|
||||
}
|
||||
}
|
||||
|
||||
func (p pokemon) ToPb() *pb.Pokemon {
|
||||
moves := make([]*pb.Move, len(p.Moves))
|
||||
for i, m := range p.Moves {
|
||||
moves[i] = m.ToPb()
|
||||
}
|
||||
|
||||
return &pb.Pokemon{
|
||||
Name: p.Name,
|
||||
Height: int32(p.Height),
|
||||
Weight: int32(p.Weight),
|
||||
Moves: moves,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
syntax = "proto3";
|
||||
//package pb; -- https://protobuf.dev/programming-guides/proto3/#packages: ignored in Go
|
||||
|
||||
option go_package = "pokedex/pb";
|
||||
|
||||
message Move {
|
||||
string name = 1;
|
||||
string url = 2;
|
||||
}
|
||||
|
||||
message Pokemons {
|
||||
repeated Pokemon entries = 1;
|
||||
}
|
||||
|
||||
message Pokemon {
|
||||
string name = 1;
|
||||
int32 height = 2;
|
||||
int32 weight = 3;
|
||||
repeated Move moves = 4;
|
||||
}
|
|
@ -15,19 +15,19 @@ func NewRepo(db *gorm.DB) Repo {
|
|||
}
|
||||
}
|
||||
|
||||
func (r Repo) Find(name string) (Pokemon, error) {
|
||||
var pokemon Pokemon
|
||||
result := r.db.Find(&pokemon, "name = ?", name) // .First() generates an error if none found
|
||||
func (r Repo) Find(name string) (pokemon, error) {
|
||||
var poke pokemon
|
||||
result := r.db.Find(&poke, "name = ?", name) // .First() generates an error if none found
|
||||
if result.Error != nil {
|
||||
return Pokemon{}, fmt.Errorf("Unable to retrive pokemon named %s: %w", name, result.Error)
|
||||
return pokemon{}, fmt.Errorf("Unable to retrive pokemon named %s: %w", name, result.Error)
|
||||
}
|
||||
|
||||
return pokemon, nil
|
||||
return poke, nil
|
||||
}
|
||||
|
||||
func (r Repo) FindAll() ([]Pokemon, error) {
|
||||
var pokemons []Pokemon
|
||||
result := r.db.Model(&Pokemon{}).Preload("Moves").Find(&pokemons)
|
||||
func (r Repo) FindAll() ([]pokemon, error) {
|
||||
var pokemons []pokemon
|
||||
result := r.db.Model(&pokemon{}).Preload("Moves").Find(&pokemons)
|
||||
if result.Error != nil {
|
||||
return nil, fmt.Errorf("Unable to retrive pokemons: %w", result.Error)
|
||||
}
|
||||
|
|
|
@ -3,13 +3,13 @@ package pokemon
|
|||
import "gorm.io/gorm"
|
||||
|
||||
func Seed(db *gorm.DB) {
|
||||
pokemons := []Pokemon{
|
||||
pokemons := []pokemon{
|
||||
{
|
||||
Id: 0,
|
||||
Name: "Jaak",
|
||||
Height: 0,
|
||||
Weight: 0,
|
||||
Moves: []Move{
|
||||
Moves: []move{
|
||||
{
|
||||
Name: "Boojakasja",
|
||||
Url: "http://sjakka.be",
|
||||
|
@ -22,8 +22,8 @@ func Seed(db *gorm.DB) {
|
|||
},
|
||||
}
|
||||
|
||||
db.AutoMigrate(&Pokemon{})
|
||||
db.AutoMigrate(&Move{})
|
||||
db.AutoMigrate(&pokemon{})
|
||||
db.AutoMigrate(&move{})
|
||||
|
||||
for _, pokemon := range pokemons {
|
||||
res := db.Create(&pokemon)
|
||||
|
|
|
@ -2,6 +2,8 @@ package rest
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
|
@ -16,6 +18,17 @@ func Json(w http.ResponseWriter, data any) {
|
|||
w.Write(bytes)
|
||||
}
|
||||
|
||||
func ProtoJson(w http.ResponseWriter, msg proto.Message) {
|
||||
bytes, err := protojson.Marshal(msg)
|
||||
if err != nil {
|
||||
http.Error(w, "Oops, something went wrong", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(bytes)
|
||||
}
|
||||
|
||||
func BadRequest(w http.ResponseWriter) {
|
||||
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue