Skip to content
Permalink
Browse files

Using the echo server framework (ep 31) (#112)

* add preliminary code

* switching to path params

* add custom middleware code

* adding JSON example

* modify comment

* adding gzip encoding

* add more comments on middleware

* episode19 => episode31

* episode31, not 19

* Moar README

* update module name

* Adding episode31 site

* oops!
  • Loading branch information...
arschles committed Sep 4, 2019
1 parent 4d1ad68 commit 4cae0d68ad60c118a346601d24d8370363bb395c
@@ -0,0 +1 @@
episode31
@@ -0,0 +1,23 @@
build:
go build -o episode31

run:
./episode31

CURL_PREAMBLE := curl -v --compressed

test-pluralize:
@echo "singular 'boat':"
${CURL_PREAMBLE} localhost:8080/pluralize/boat?num=1
@echo ""
@echo "plural 'boat':"
${CURL_PREAMBLE} localhost:8080/pluralize/boat?num=2
@echo ""

test-middleware:
${CURL_PREAMBLE} localhost:8080/request_count
@echo ""

test-json:
${CURL_PREAMBLE} -H "Content-Type: application/json" -XPOST -d '{"x":123,"y":456}' localhost:8080/json
@echo ""
@@ -0,0 +1,17 @@
# The Echo HTTP Server Framework

Go in 5 Minutes, episode 31.

This screencast overviews [Echo HTTP Server Framework](https://github.com/labstack/echo). It's a response to [issue #98](https://github.com/arschles/go-in-5-minutes/issues/98).

# Outline

1. The basics
1. Middlewares
1. Example code

# Show notes

- [Echo framework homepage](https://echo.labstack.com/)
- [Echo framework GitHub page](https://github.com/labstack/echo)
- [Article about what middleware is in Go](https://hackernoon.com/simple-http-middleware-with-go-79a4ad62889b)
@@ -0,0 +1,25 @@
package main

import (
"fmt"
"net/http"
"sync/atomic"

"github.com/labstack/echo"
)

// requestCounter is both a middleware that counts the number of incoming requests, and a handler that can return that number
type requestCounter struct {
counter int64
}

func (r *requestCounter) Process(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
atomic.AddInt64(&r.counter, 1)
return next(c)
}
}

func (r *requestCounter) handle(c echo.Context) error {
return c.String(http.StatusOK, fmt.Sprintf("%d", atomic.LoadInt64(&r.counter)))
}
@@ -0,0 +1,11 @@
module github.com/arschles/go-in-5-minutes/episode31

go 1.12

require (
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813
github.com/labstack/echo v3.3.10+incompatible
github.com/labstack/gommon v0.3.0 // indirect
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 // indirect
)
@@ -0,0 +1,34 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813 h1:Uc+IZ7gYqAf/rSGFplbWBSHaGolEQlNLgMgSE3ccnIQ=
github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813/go.mod h1:P+oSoE9yhSRvsmYyZsshflcR6ePWYLql6UU1amW13IM=
github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg=
github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s=
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 h1:Gv7RPwsi3eZ2Fgewe3CBsuOebPwO27PoXzRpJPsvSSM=
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ -0,0 +1,24 @@
package main

import (
"fmt"
"net/http"

"github.com/labstack/echo"
)

type coordinates struct {
X int `json:"x" xml:"x" form:"x"`
Y int `json:"y" xml:"y" form:"y"`
}

func jsonHandler(c echo.Context) error {
coords := new(coordinates)
if err := c.Bind(coords); err != nil {
return err
}
return c.String(
http.StatusOK,
fmt.Sprintf("x coord = %d, y coord = %d", coords.X, coords.Y),
)
}
@@ -0,0 +1,46 @@
package main

import (
"fmt"

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

func main() {
e := echo.New()

/////
// Setting up basic middleware(s). There are lots of other built-in middlewares, including:
//
// 1. CSRF prevention: https://echo.labstack.com/middleware/csrf
// 2. CORS support: https://echo.labstack.com/middleware/cors
// 3. JWT support: https://echo.labstack.com/middleware/jwt
// 4. HTTPS redirects: https://echo.labstack.com/middleware/redirect
/////
e.Use(middleware.Logger())
e.Use(middleware.Gzip())
reqCounter := requestCounter{}
e.Use(reqCounter.Process)

/////
// path and query params (simple)
/////
e.GET(fmt.Sprintf("/pluralize/:%s", singularPathParam), pluralizeHandler)

/////
// use the request counter middleware to return the number of incoming requests
/////
e.GET("/request_count", reqCounter.handle)

/////
// accept a JSON body
/////
e.POST("/json", jsonHandler)

const port = 8080
e.Logger.Printf("starting on port %d", port)
if err := e.Start(fmt.Sprintf(":%d", port)); err != nil {
e.Logger.Fatal(err.Error())
}
}
@@ -0,0 +1,28 @@
package main

import (
"net/http"
"strconv"

"github.com/gedex/inflector"
"github.com/labstack/echo"
)

const singularPathParam = "singular"

func pluralizeHandler(c echo.Context) error {
singular := c.Param(singularPathParam)
numStr := c.QueryParam("num")
num, err := strconv.Atoi(numStr)
if err != nil {
c.Logger().Errorf("'num' query param %s is not a number", numStr)
return err
}

// singular case
if num == 1 {
return c.String(http.StatusOK, singular)
}
// plural case
return c.String(http.StatusOK, inflector.Pluralize(singular))
}
@@ -0,0 +1,24 @@
+++
type = "screencast"
title = "Building Fast Web Apps with the Echo Framework!"
teaser = "Learn how to use the Echo framework to quickly write highquality web services."
author = "Aaron Schlesinger"
date = "2019-09-04T15:22:28-07:00"
+++

_Episode 13_

Learn how to use the [Echo](https://echo.labstack.com/) framework to write quick and high-quality web services.

<!--more-->

[Echo](https://echo.labstack.com/) is a web framework that strikes a really good balance between ease of use and quality. Its API is very straightforward and encourages you to follow best practices (in some cases, it adds barriers to making mistakes!)

Check out the screencast to learn how to take advantage of Echo to write your next web service.

Keep on rockin', Gophers!

<iframe width="560" height="315" src="https://www.youtube.com/embed/aCMcKq5G_xM" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

Check out the example code [on Github](https://github.com/arschles/go-in-5-minutes/tree/master/episode31).

0 comments on commit 4cae0d6

Please sign in to comment.
You can’t perform that action at this time.