Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions echo/Notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Open topics:

- How to use model without adding tags?
- How to redirect with custom HTTP Method (defaults to "POST")?
- Org url structure when BE API and FE served from the same app
- Refactor API urls (maybe group them)


API:

/api

Static / Assets:

/static

Front-end / Website:

/


91 changes: 91 additions & 0 deletions echo/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package main

import (
"net/http"
"strconv"

"github.com/CoderVlogger/go-web-frameworks/pkg"
"github.com/labstack/echo/v4"
)

func (wa *WebApplication) initAPIRoutes() {
wa.echoApp.POST(apiPrefix+"entities", wa.addEntity)
wa.echoApp.PUT(apiPrefix+"entities", wa.updateEntity)
wa.echoApp.GET(apiPrefix+"entities", wa.listEntities)
wa.echoApp.GET(apiPrefix+"entities/:id", wa.getEntity)
wa.echoApp.DELETE(apiPrefix+"entities/:id", wa.deleteEntity)
}

func (wa *WebApplication) addEntity(ctx echo.Context) error {
entity := pkg.Entity{}

if err := ctx.Bind(&entity); err != nil {
return ctx.JSON(http.StatusBadRequest, pkg.TextResponse{Message: err.Error()})
}

if err := wa.entityRepository.Add(&entity); err != nil {
return ctx.JSON(http.StatusInternalServerError, pkg.TextResponse{Message: err.Error()})
}

return ctx.JSON(http.StatusCreated, entity)
}

func (wa *WebApplication) updateEntity(ctx echo.Context) error {
entity := pkg.Entity{}

if err := ctx.Bind(&entity); err != nil {
return ctx.JSON(http.StatusBadRequest, pkg.TextResponse{Message: err.Error()})
}

if err := wa.entityRepository.Update(&entity); err != nil {
return ctx.JSON(http.StatusInternalServerError, pkg.TextResponse{Message: err.Error()})
}

return ctx.JSON(http.StatusOK, entity)
}

func (wa *WebApplication) getEntity(ctx echo.Context) error {
entityID := ctx.Param("id")

entity, err := wa.entityRepository.Get(entityID)
if err != nil {
return ctx.JSON(http.StatusNotFound, pkg.TextResponse{Message: err.Error()})
}

if entity == nil {
return ctx.JSON(http.StatusNotFound, pkg.TextResponse{Message: "entity not found"})
}

return ctx.JSON(http.StatusOK, entity)
}

func (wa *WebApplication) listEntities(ctx echo.Context) error {
var err error

page := 1

pageStr := ctx.QueryParam("page")
if pageStr != "" {
page, err = strconv.Atoi(pageStr)
if err != nil {
return ctx.JSON(http.StatusBadRequest, pkg.TextResponse{Message: err.Error()})
}
}

entities, err := wa.entityRepository.List(page, pageSize)
if err != nil {
return ctx.JSON(http.StatusBadRequest, pkg.TextResponse{Message: err.Error()})
}

return ctx.JSON(http.StatusOK, entities)
}

func (wa *WebApplication) deleteEntity(ctx echo.Context) error {
entityID := ctx.Param("id")

if err := wa.entityRepository.Delete(entityID); err != nil {
return ctx.JSON(http.StatusInternalServerError, pkg.TextResponse{Message: err.Error()})
}

return ctx.JSON(http.StatusOK, pkg.TextResponse{Message: "entity deleted"})
}
1 change: 1 addition & 0 deletions echo/assets/js/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log("demo")
25 changes: 25 additions & 0 deletions echo/assets/pages/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

<body>
<h1>Echo</h1>

<h2>Submit a new entity:</h2>

<!-- action defaults to the same page -->
<form method="post">
<label for="type">Type:</label>
<input type="text" id="type" name="type" />
<br /><br />

<label for="name">Name:</label>
<input type="text" id="name" name="name" />
<br /><br />

<label for="description">Description:</label>
<input type="text" id="description" name="description" />
<br /><br />

<input type="submit" value="Send!" />
</form>

<script src="/static/js/index.js"></script>
</body>
6 changes: 3 additions & 3 deletions echo/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.17
replace github.com/CoderVlogger/go-web-frameworks/pkg => ../pkg

require (
github.com/CoderVlogger/go-web-frameworks/pkg v0.0.0-00010101000000-000000000000
github.com/CoderVlogger/go-web-frameworks/pkg v0.0.0-20220207162710-24ad69459d6b
github.com/labstack/echo/v4 v4.6.3
)

Expand All @@ -15,8 +15,8 @@ require (
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.1 // indirect
golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838 // indirect
golang.org/x/crypto v0.0.0-20220208050332-20e1d8d225ab // indirect
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 // indirect
golang.org/x/sys v0.0.0-20220207234003-57398862261d // indirect
golang.org/x/text v0.3.7 // indirect
)
8 changes: 4 additions & 4 deletions echo/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838 h1:71vQrMauZZhcTVK6KdYM+rklehEEwb3E+ZhaE5jrPrE=
golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220208050332-20e1d8d225ab h1:lnZ4LoV0UMdibeCUfIB2a4uFwRu491WX/VB2reB8xNc=
golang.org/x/crypto v0.0.0-20220208050332-20e1d8d225ab/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210913180222-943fd674d43e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
Expand All @@ -35,8 +35,8 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 h1:XDXtA5hveEEV8JB2l7nhMTp3t3cHp9ZpwcdjqyEWLlo=
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220207234003-57398862261d h1:Bm7BNOQt2Qv7ZqysjeLjgCBanX+88Z/OtdvsrEv1Djc=
golang.org/x/sys v0.0.0-20220207234003-57398862261d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
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/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
Expand Down
103 changes: 20 additions & 83 deletions echo/server.go
Original file line number Diff line number Diff line change
@@ -1,106 +1,43 @@
package main

import (
"net/http"
"strconv"

"github.com/CoderVlogger/go-web-frameworks/pkg"

"github.com/labstack/echo/v4"
)

var (
pageSize = 4
entityStorage pkg.EntityRepository = pkg.NewEntityMemoryRepository()
pageSize = 4
apiPrefix = "/api/"
)

func main() {
app := echo.New()
entityStorage.Init()

app.GET("/", func(c echo.Context) error {
return c.String(http.StatusOK, "Hello, Echo!")
})

app.POST("/entities", addEntity)
app.PUT("/entities", updateEntity)
app.GET("/entities", listEntities)
app.GET("/entities/:id", getEntity)
app.DELETE("/entities/:id", deleteEntity)

app.Logger.Fatal(app.Start(":8080"))
type WebApplication struct {
echoApp *echo.Echo
entityRepository pkg.EntityRepository
}

func addEntity(ctx echo.Context) error {
entity := pkg.Entity{}

if err := ctx.Bind(&entity); err != nil {
return ctx.JSON(http.StatusBadRequest, pkg.TextResponse{Message: err.Error()})
}
func NewWebApplication() *WebApplication {
er := pkg.NewEntityMemoryRepository()
er.Init()

if err := entityStorage.Add(&entity); err != nil {
return ctx.JSON(http.StatusInternalServerError, pkg.TextResponse{Message: err.Error()})
return &WebApplication{
echoApp: echo.New(),
entityRepository: er,
}

return ctx.JSON(http.StatusCreated, entity)
}

func updateEntity(ctx echo.Context) error {
entity := pkg.Entity{}

if err := ctx.Bind(&entity); err != nil {
return ctx.JSON(http.StatusBadRequest, pkg.TextResponse{Message: err.Error()})
}

if err := entityStorage.Update(&entity); err != nil {
return ctx.JSON(http.StatusInternalServerError, pkg.TextResponse{Message: err.Error()})
}

return ctx.JSON(http.StatusOK, entity)
func (wa *WebApplication) Init() {
wa.initAPIRoutes()
wa.initWebsite()
}

func getEntity(ctx echo.Context) error {
entityID := ctx.Param("id")

entity, err := entityStorage.Get(entityID)
if err != nil {
return ctx.JSON(http.StatusNotFound, pkg.TextResponse{Message: err.Error()})
}

if entity == nil {
return ctx.JSON(http.StatusNotFound, pkg.TextResponse{Message: "entity not found"})
}

return ctx.JSON(http.StatusOK, entity)
}

func listEntities(ctx echo.Context) error {
var err error

page := 1

pageStr := ctx.QueryParam("page")
if pageStr != "" {
page, err = strconv.Atoi(pageStr)
if err != nil {
return ctx.JSON(http.StatusBadRequest, pkg.TextResponse{Message: err.Error()})
}
}

entities, err := entityStorage.List(page, pageSize)
if err != nil {
return ctx.JSON(http.StatusBadRequest, pkg.TextResponse{Message: err.Error()})
}

return ctx.JSON(http.StatusOK, entities)
func (wa *WebApplication) Start(address string) {
wa.echoApp.Logger.Fatal(wa.echoApp.Start(address))
}

func deleteEntity(ctx echo.Context) error {
entityID := ctx.Param("id")

if err := entityStorage.Delete(entityID); err != nil {
return ctx.JSON(http.StatusInternalServerError, pkg.TextResponse{Message: err.Error()})
}
func main() {
wa := NewWebApplication()

return ctx.JSON(http.StatusOK, pkg.TextResponse{Message: "entity deleted"})
wa.Init()
wa.Start(":8080")
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion echo/vendor/golang.org/x/sys/unix/syscall_linux.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions echo/vendor/golang.org/x/sys/unix/syscall_linux_alarm.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion echo/vendor/golang.org/x/sys/unix/zerrors_linux.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 12 additions & 1 deletion echo/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 12 additions & 1 deletion echo/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading