mirror of
https://github.com/labstack/echo.git
synced 2025-11-06 08:59:21 +02:00
7
recipes/google-app-engine/Dockerfile
Normal file
7
recipes/google-app-engine/Dockerfile
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Dockerfile extending the generic Go image with application files for a
|
||||||
|
# single application.
|
||||||
|
FROM gcr.io/google_appengine/golang
|
||||||
|
|
||||||
|
COPY . /go/src/app
|
||||||
|
RUN go-wrapper download
|
||||||
|
RUN go-wrapper install -tags appenginevm
|
||||||
18
recipes/google-app-engine/app-engine.go
Normal file
18
recipes/google-app-engine/app-engine.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
// +build appengine
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/labstack/echo"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func createMux() *echo.Echo {
|
||||||
|
e := echo.New()
|
||||||
|
|
||||||
|
// note: we don't need to provide the middleware or static handlers, that's taken care of by the platform
|
||||||
|
// app engine has it's own "main" wrapper - we just need to hook echo into the default handler
|
||||||
|
http.Handle("/", e)
|
||||||
|
|
||||||
|
return e
|
||||||
|
}
|
||||||
36
recipes/google-app-engine/app-engine.yaml
Normal file
36
recipes/google-app-engine/app-engine.yaml
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
application: my-application-id # defined when you create your app using google dev console
|
||||||
|
module: default # see https://cloud.google.com/appengine/docs/go/
|
||||||
|
version: alpha # you can run multiple versions of an app and A/B test
|
||||||
|
runtime: go # see https://cloud.google.com/appengine/docs/go/
|
||||||
|
api_version: go1 # used when appengine supports different go versions
|
||||||
|
|
||||||
|
default_expiration: "1d" # for CDN serving of static files (use url versioning if long!)
|
||||||
|
|
||||||
|
handlers:
|
||||||
|
# all the static files that we normally serve ourselves are defined here and Google will handle
|
||||||
|
# serving them for us from it's own CDN / edge locations. For all the configuration options see:
|
||||||
|
# https://cloud.google.com/appengine/docs/go/config/appconfig#Go_app_yaml_Static_file_handlers
|
||||||
|
- url: /
|
||||||
|
mime_type: text/html
|
||||||
|
static_files: public/index.html
|
||||||
|
upload: public/index.html
|
||||||
|
|
||||||
|
- url: /favicon.ico
|
||||||
|
mime_type: image/x-icon
|
||||||
|
static_files: public/favicon.ico
|
||||||
|
upload: public/favicon.ico
|
||||||
|
|
||||||
|
- url: /scripts
|
||||||
|
mime_type: text/javascript
|
||||||
|
static_dir: public/scripts
|
||||||
|
|
||||||
|
# static files normally don't touch the server that the app runs on but server-side template files
|
||||||
|
# needs to be readable by the app. The application_readable option makes sure they are available as
|
||||||
|
# part of the app deployment onto the instance.
|
||||||
|
- url: /templates
|
||||||
|
static_dir: /templates
|
||||||
|
application_readable: true
|
||||||
|
|
||||||
|
# finally, we route all other requests to our application. The script name just means "the go app"
|
||||||
|
- url: /.*
|
||||||
|
script: _go_app
|
||||||
29
recipes/google-app-engine/app-managed.go
Normal file
29
recipes/google-app-engine/app-managed.go
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
// +build appenginevm
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/labstack/echo"
|
||||||
|
"google.golang.org/appengine"
|
||||||
|
"net/http"
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func createMux() *echo.Echo {
|
||||||
|
// we're in a container on a Google Compute Engine instance so are not sandboxed anymore ...
|
||||||
|
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||||
|
|
||||||
|
e := echo.New()
|
||||||
|
|
||||||
|
// note: we don't need to provide the middleware or static handlers
|
||||||
|
// for the appengine vm version - that's taken care of by the platform
|
||||||
|
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// the appengine package provides a convenient method to handle the health-check requests
|
||||||
|
// and also run the app on the correct port. We just need to add Echo to the default handler
|
||||||
|
http.Handle("/", e)
|
||||||
|
appengine.Main()
|
||||||
|
}
|
||||||
37
recipes/google-app-engine/app-managed.yaml
Normal file
37
recipes/google-app-engine/app-managed.yaml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
application: my-application-id # defined when you create your app using google dev console
|
||||||
|
module: default # see https://cloud.google.com/appengine/docs/go/
|
||||||
|
version: alpha # you can run multiple versions of an app and A/B test
|
||||||
|
runtime: go # see https://cloud.google.com/appengine/docs/go/
|
||||||
|
api_version: go1 # used when appengine supports different go versions
|
||||||
|
vm: true # for managed VMs only, remove for appengine classic
|
||||||
|
|
||||||
|
default_expiration: "1d" # for CDN serving of static files (use url versioning if long!)
|
||||||
|
|
||||||
|
handlers:
|
||||||
|
# all the static files that we normally serve ourselves are defined here and Google will handle
|
||||||
|
# serving them for us from it's own CDN / edge locations. For all the configuration options see:
|
||||||
|
# https://cloud.google.com/appengine/docs/go/config/appconfig#Go_app_yaml_Static_file_handlers
|
||||||
|
- url: /
|
||||||
|
mime_type: text/html
|
||||||
|
static_files: public/index.html
|
||||||
|
upload: public/index.html
|
||||||
|
|
||||||
|
- url: /favicon.ico
|
||||||
|
mime_type: image/x-icon
|
||||||
|
static_files: public/favicon.ico
|
||||||
|
upload: public/favicon.ico
|
||||||
|
|
||||||
|
- url: /scripts
|
||||||
|
mime_type: text/javascript
|
||||||
|
static_dir: public/scripts
|
||||||
|
|
||||||
|
# static files normally don't touch the server that the app runs on but server-side template files
|
||||||
|
# needs to be readable by the app. The application_readable option makes sure they are available as
|
||||||
|
# part of the app deployment onto the instance.
|
||||||
|
- url: /templates
|
||||||
|
static_dir: /templates
|
||||||
|
application_readable: true
|
||||||
|
|
||||||
|
# finally, we route all other requests to our application. The script name just means "the go app"
|
||||||
|
- url: /.*
|
||||||
|
script: _go_app
|
||||||
25
recipes/google-app-engine/app-standalone.go
Normal file
25
recipes/google-app-engine/app-standalone.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// +build !appengine,!appenginevm
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/labstack/echo"
|
||||||
|
"github.com/labstack/echo/middleware"
|
||||||
|
)
|
||||||
|
|
||||||
|
func createMux() *echo.Echo {
|
||||||
|
e := echo.New()
|
||||||
|
|
||||||
|
e.Use(middleware.Recover())
|
||||||
|
e.Use(middleware.Logger())
|
||||||
|
e.Use(middleware.Gzip())
|
||||||
|
|
||||||
|
e.Index("public/index.html")
|
||||||
|
e.Static("/public", "public")
|
||||||
|
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
e.Run(":8080")
|
||||||
|
}
|
||||||
4
recipes/google-app-engine/app.go
Normal file
4
recipes/google-app-engine/app.go
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
// referecnce our echo instance and create it early
|
||||||
|
var e = createMux()
|
||||||
BIN
recipes/google-app-engine/public/favicon.ico
Normal file
BIN
recipes/google-app-engine/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
15
recipes/google-app-engine/public/index.html
Normal file
15
recipes/google-app-engine/public/index.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||||
|
<title>Echo</title>
|
||||||
|
<link rel="shortcut icon" href="favicon.ico" />
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Echo!</h1>
|
||||||
|
<script src="/scripts/main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
1
recipes/google-app-engine/public/scripts/main.js
Normal file
1
recipes/google-app-engine/public/scripts/main.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
console.log("Echo!");
|
||||||
1
recipes/google-app-engine/templates/welcome.html
Normal file
1
recipes/google-app-engine/templates/welcome.html
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{{define "welcome"}}Hello, {{.}}!{{end}}
|
||||||
54
recipes/google-app-engine/users.go
Normal file
54
recipes/google-app-engine/users.go
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/labstack/echo"
|
||||||
|
"github.com/rs/cors"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
user struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
users map[string]user
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
users = map[string]user{
|
||||||
|
"1": user{
|
||||||
|
ID: "1",
|
||||||
|
Name: "Wreck-It Ralph",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// hook into the echo instance to create an endpoint group
|
||||||
|
// and add specific middleware to it plus handlers
|
||||||
|
g := e.Group("/users")
|
||||||
|
g.Use(cors.Default().Handler)
|
||||||
|
|
||||||
|
g.Post("", createUser)
|
||||||
|
g.Get("", getUsers)
|
||||||
|
g.Get("/:id", getUser)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createUser(c *echo.Context) error {
|
||||||
|
u := new(user)
|
||||||
|
if err := c.Bind(u); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
users[u.ID] = *u
|
||||||
|
return c.JSON(http.StatusCreated, u)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getUsers(c *echo.Context) error {
|
||||||
|
return c.JSON(http.StatusOK, users)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getUser(c *echo.Context) error {
|
||||||
|
return c.JSON(http.StatusOK, users[c.P(0)])
|
||||||
|
}
|
||||||
31
recipes/google-app-engine/welcome.go
Normal file
31
recipes/google-app-engine/welcome.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"html/template"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/labstack/echo"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
Template struct {
|
||||||
|
templates *template.Template
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
t := &Template{
|
||||||
|
templates: template.Must(template.ParseFiles("templates/welcome.html")),
|
||||||
|
}
|
||||||
|
e.SetRenderer(t)
|
||||||
|
e.Get("/welcome", welcome)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Template) Render(w io.Writer, name string, data interface{}) error {
|
||||||
|
return t.templates.ExecuteTemplate(w, name, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func welcome(c *echo.Context) error {
|
||||||
|
return c.Render(http.StatusOK, "welcome", "Joe")
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ menu:
|
|||||||
Use `req.ParseMultipartForm(16 << 20)` for manually parsing multipart form. It gives
|
Use `req.ParseMultipartForm(16 << 20)` for manually parsing multipart form. It gives
|
||||||
us an option to specify the maximum memory used while parsing the request body.
|
us an option to specify the maximum memory used while parsing the request body.
|
||||||
|
|
||||||
## Server
|
### Server
|
||||||
|
|
||||||
`server.go`
|
`server.go`
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Client
|
### Client
|
||||||
|
|
||||||
`index.html`
|
`index.html`
|
||||||
|
|
||||||
@@ -96,8 +96,8 @@ func main() {
|
|||||||
</html>
|
</html>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Maintainers
|
### Maintainers
|
||||||
|
|
||||||
- [vishr](http://github.com/vishr)
|
- [vishr](http://github.com/vishr)
|
||||||
|
|
||||||
## [Source Code](https://github.com/labstack/echo/blob/master/recipes/file-upload)
|
### [Source Code](https://github.com/labstack/echo/blob/master/recipes/file-upload)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: Google App Engine
|
title: Google App Engine
|
||||||
draft: true
|
draft: false
|
||||||
menu:
|
menu:
|
||||||
main:
|
main:
|
||||||
parent: recipes
|
parent: recipes
|
||||||
@@ -241,7 +241,7 @@ be executed locally, on a full Compute Engine instance or any other traditional
|
|||||||
(including EC2, Docker etc...). This build will ignore the code in appengine and appenginevm tagged
|
(including EC2, Docker etc...). This build will ignore the code in appengine and appenginevm tagged
|
||||||
files and the `app.yaml` file is meaningless to anything other than the AppEngine platform.
|
files and the `app.yaml` file is meaningless to anything other than the AppEngine platform.
|
||||||
|
|
||||||
We can also run locally using the [Google AppEngine SDK for GO](https://cloud.google.com/appengine/downloads)
|
We can also run locally using the [Google AppEngine SDK for Go](https://cloud.google.com/appengine/downloads)
|
||||||
either emulating [AppEngine Classic](https://cloud.google.com/appengine/docs/go/tools/devserver):
|
either emulating [AppEngine Classic](https://cloud.google.com/appengine/docs/go/tools/devserver):
|
||||||
|
|
||||||
goapp serve
|
goapp serve
|
||||||
@@ -258,4 +258,8 @@ switching between AppEngine provided service such as Datastore and alternative s
|
|||||||
such as MongoDB. A combination of go interfaces and build constraints can make this fairly straightforward
|
such as MongoDB. A combination of go interfaces and build constraints can make this fairly straightforward
|
||||||
but is outside the scope of this recipe.
|
but is outside the scope of this recipe.
|
||||||
|
|
||||||
## [Source Code](https://github.com/labstack/echo/blob/master/recipes/google-app-engine)
|
### Maintainers
|
||||||
|
|
||||||
|
- [CaptainCodeman](https://github.com/CaptainCodeman)
|
||||||
|
|
||||||
|
### [Source Code](https://github.com/labstack/echo/blob/master/recipes/google-app-engine)
|
||||||
|
|||||||
@@ -56,12 +56,12 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Maintainers
|
### Maintainers
|
||||||
|
|
||||||
- (mertenvg)[https://github.com/mertenvg]
|
- [mertenvg](https://github.com/mertenvg)
|
||||||
|
|
||||||
## Source Code
|
### Source Code
|
||||||
|
|
||||||
[`graceful`](https://github.com/labstack/echo/blob/master/recipes/graceful-shutdown/graceful)
|
[graceful](https://github.com/labstack/echo/blob/master/recipes/graceful-shutdown/graceful)
|
||||||
|
|
||||||
[`grace`](https://github.com/labstack/echo/blob/master/recipes/graceful-shutdown/grace)
|
[grace](https://github.com/labstack/echo/blob/master/recipes/graceful-shutdown/grace)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ menu:
|
|||||||
|
|
||||||
JSONP is a method that allows cross-domain server calls. You can read more about it at the JSON versus JSONP Tutorial.
|
JSONP is a method that allows cross-domain server calls. You can read more about it at the JSON versus JSONP Tutorial.
|
||||||
|
|
||||||
## Server
|
### Server
|
||||||
|
|
||||||
`server.go`
|
`server.go`
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Client
|
### Client
|
||||||
|
|
||||||
`index.html`
|
`index.html`
|
||||||
|
|
||||||
@@ -88,8 +88,8 @@ func main() {
|
|||||||
</html>
|
</html>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Maintainers
|
### Maintainers
|
||||||
|
|
||||||
- [willf](http://github.com/willf)
|
- [willf](http://github.com/willf)
|
||||||
|
|
||||||
## [Source Code](https://github.com/labstack/echo/blob/master/recipes/jsonp)
|
### [Source Code](https://github.com/labstack/echo/blob/master/recipes/jsonp)
|
||||||
|
|||||||
@@ -153,8 +153,8 @@ func main() {
|
|||||||
$ curl localhost:1323/restricted -H "Authorization: Bearer <token>" => Access granted with JWT.
|
$ curl localhost:1323/restricted -H "Authorization: Bearer <token>" => Access granted with JWT.
|
||||||
```
|
```
|
||||||
|
|
||||||
## Maintainers
|
### Maintainers
|
||||||
|
|
||||||
- [axdg](http://github.com/axdg)
|
- [axdg](http://github.com/axdg)
|
||||||
|
|
||||||
## [Source Code](https://github.com/labstack/echo/blob/master/recipes/jwt-authentication)
|
### [Source Code](https://github.com/labstack/echo/blob/master/recipes/jwt-authentication)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ menu:
|
|||||||
- Streaming multipart/form-data file upload
|
- Streaming multipart/form-data file upload
|
||||||
- Multiple form fields and files
|
- Multiple form fields and files
|
||||||
|
|
||||||
## Server
|
### Server
|
||||||
|
|
||||||
`server.go`
|
`server.go`
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Client
|
### Client
|
||||||
|
|
||||||
`index.html`
|
`index.html`
|
||||||
|
|
||||||
@@ -118,8 +118,8 @@ func main() {
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Maintainers
|
### Maintainers
|
||||||
|
|
||||||
- [vishr](http://github.com/vishr)
|
- [vishr](http://github.com/vishr)
|
||||||
|
|
||||||
## [Source Code](https://github.com/labstack/echo/blob/master/recipes/streaming-file-upload)
|
### [Source Code](https://github.com/labstack/echo/blob/master/recipes/streaming-file-upload)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ menu:
|
|||||||
- Send data as it is produced
|
- Send data as it is produced
|
||||||
- Streaming JSON response with chunked transfer encoding
|
- Streaming JSON response with chunked transfer encoding
|
||||||
|
|
||||||
## Server
|
### Server
|
||||||
|
|
||||||
`server.go`
|
`server.go`
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Client
|
### Client
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ curl localhost:1323
|
$ curl localhost:1323
|
||||||
@@ -76,8 +76,8 @@ $ curl localhost:1323
|
|||||||
{"Altitude":15,"Latitude":37.77493,"Longitude":-122.419416}
|
{"Altitude":15,"Latitude":37.77493,"Longitude":-122.419416}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Maintainers
|
### Maintainers
|
||||||
|
|
||||||
- [vishr](http://github.com/vishr)
|
- [vishr](http://github.com/vishr)
|
||||||
|
|
||||||
## [Source Code](https://github.com/labstack/echo/blob/master/recipes/streaming-response)
|
### [Source Code](https://github.com/labstack/echo/blob/master/recipes/streaming-response)
|
||||||
|
|||||||
@@ -77,9 +77,9 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Maintainers
|
### Maintainers
|
||||||
|
|
||||||
- [axdg](http://github.com/axdg)
|
- [axdg](http://github.com/axdg)
|
||||||
- [vishr](http://github.com/axdg)
|
- [vishr](http://github.com/axdg)
|
||||||
|
|
||||||
## [Source Code](https://github.com/labstack/echo/blob/master/recipes/subdomains)
|
### [Source Code](https://github.com/labstack/echo/blob/master/recipes/subdomains)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ menu:
|
|||||||
parent: recipes
|
parent: recipes
|
||||||
---
|
---
|
||||||
|
|
||||||
## Server
|
### Server
|
||||||
|
|
||||||
`server.go`
|
`server.go`
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Client
|
### Client
|
||||||
|
|
||||||
`index.html`
|
`index.html`
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ func main() {
|
|||||||
</html>
|
</html>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Output
|
### Output
|
||||||
|
|
||||||
`Client`
|
`Client`
|
||||||
|
|
||||||
@@ -112,8 +112,8 @@ Hello, Server!
|
|||||||
Hello, Server!
|
Hello, Server!
|
||||||
```
|
```
|
||||||
|
|
||||||
## Maintainers
|
### Maintainers
|
||||||
|
|
||||||
- [vishr](http://github.com/vishr)
|
- [vishr](http://github.com/vishr)
|
||||||
|
|
||||||
## [Source Code](https://github.com/labstack/echo/blob/master/recipes/websocket)
|
### [Source Code](https://github.com/labstack/echo/blob/master/recipes/websocket)
|
||||||
|
|||||||
Reference in New Issue
Block a user