mirror of
https://github.com/kataras/iris.git
synced 2025-12-20 03:17:04 +00:00
reorganization of _examples and add some new examples such as iris+groupcache+mysql+docker
Former-commit-id: ed635ee95de7160cde11eaabc0c1dcb0e460a620
This commit is contained in:
3
_examples/routing/basic/.dockerignore
Normal file
3
_examples/routing/basic/.dockerignore
Normal file
@@ -0,0 +1,3 @@
|
||||
.git
|
||||
node_modules
|
||||
bin
|
||||
17
_examples/routing/basic/Dockerfile
Normal file
17
_examples/routing/basic/Dockerfile
Normal file
@@ -0,0 +1,17 @@
|
||||
# docker build -t myapp .
|
||||
# docker run --rm -it -p 8080:8080 myapp:latest
|
||||
FROM golang:latest AS builder
|
||||
RUN apt-get update
|
||||
ENV GO111MODULE=on \
|
||||
CGO_ENABLED=0 \
|
||||
GOOS=linux \
|
||||
GOARCH=amd64
|
||||
WORKDIR /go/src/app
|
||||
COPY go.mod .
|
||||
RUN go mod download
|
||||
COPY . .
|
||||
RUN go install
|
||||
|
||||
FROM scratch
|
||||
COPY --from=builder /go/bin/app .
|
||||
ENTRYPOINT ["./app"]
|
||||
27
_examples/routing/basic/README.md
Normal file
27
_examples/routing/basic/README.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Basic Example
|
||||
|
||||
The only requirement for this example is [Docker](https://docs.docker.com/install/).
|
||||
|
||||
## Docker Compose
|
||||
|
||||
The Docker Compose is pre-installed with Docker for Windows. For linux please follow the steps described at: https://docs.docker.com/compose/install/.
|
||||
|
||||
Build and run the application for linux arch and expose it on http://localhost:8080.
|
||||
|
||||
```sh
|
||||
$ docker-compose up
|
||||
```
|
||||
|
||||
See [docker-compose file](docker-compose.yml).
|
||||
|
||||
## Without Docker Compose
|
||||
|
||||
1. Build the image as "myapp" (docker build)
|
||||
2. Run the image and map exposed ports (-p 8080:8080)
|
||||
3. Attach the interactive mode so CTRL/CMD+C signals are respected to shutdown the Iris Server (-it)
|
||||
4. Cleanup the image on finish (--rm)
|
||||
|
||||
```sh
|
||||
$ docker build -t myapp .
|
||||
$ docker run --rm -it -p 8080:8080 myapp:latest
|
||||
```
|
||||
8
_examples/routing/basic/docker-compose.yml
Normal file
8
_examples/routing/basic/docker-compose.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
# docker-compose up [--build]
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
app:
|
||||
build: .
|
||||
ports:
|
||||
- 8080:8080
|
||||
@@ -133,7 +133,7 @@ func newApp() *iris.Application {
|
||||
{ // braces are optional, it's just type of style, to group the routes visually.
|
||||
|
||||
// http://v1.localhost:8080
|
||||
// Note: for versioning-specific features checkout the _examples/versioning instead.
|
||||
// Note: for versioning-specific features checkout the _examples/routing/versioning instead.
|
||||
v1.Get("/", func(ctx iris.Context) {
|
||||
ctx.HTML(`Version 1 API. go to <a href="/api/users">/api/users</a>`)
|
||||
})
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
// The tests are written in a way to be easy to understand,
|
||||
// for a more comprehensive testing examples check out the:
|
||||
// _examples/routing/main_test.go,
|
||||
// _examples/subdomains/www/main_test.go
|
||||
// _examples/routing/subdomains/www/main_test.go
|
||||
// _examples/file-server and e.t.c.
|
||||
// Almost every example which covers
|
||||
// a new feature from you to learn
|
||||
|
||||
42
_examples/routing/hello-world/main.go
Normal file
42
_examples/routing/hello-world/main.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/v12"
|
||||
|
||||
"github.com/kataras/iris/v12/middleware/logger"
|
||||
"github.com/kataras/iris/v12/middleware/recover"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
app.Logger().SetLevel("debug")
|
||||
// Optionally, add two builtin handlers
|
||||
// that can recover from any http-relative panics
|
||||
// and log the requests to the terminal.
|
||||
app.Use(recover.New())
|
||||
app.Use(logger.New())
|
||||
|
||||
// Method: GET
|
||||
// Resource: http://localhost:8080
|
||||
app.Handle("GET", "/", func(ctx iris.Context) {
|
||||
ctx.HTML("<h1>Welcome</h1>")
|
||||
})
|
||||
|
||||
// same as app.Handle("GET", "/ping", [...])
|
||||
// Method: GET
|
||||
// Resource: http://localhost:8080/ping
|
||||
app.Get("/ping", func(ctx iris.Context) {
|
||||
ctx.WriteString("pong")
|
||||
})
|
||||
|
||||
// Method: GET
|
||||
// Resource: http://localhost:8080/hello
|
||||
app.Get("/hello", func(ctx iris.Context) {
|
||||
ctx.JSON(iris.Map{"message": "Hello Iris!"})
|
||||
})
|
||||
|
||||
// http://localhost:8080
|
||||
// http://localhost:8080/ping
|
||||
// http://localhost:8080/hello
|
||||
app.Listen(":8080")
|
||||
}
|
||||
126
_examples/routing/overview-2/main.go
Normal file
126
_examples/routing/overview-2/main.go
Normal file
@@ -0,0 +1,126 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/v12"
|
||||
)
|
||||
|
||||
// User is just a bindable object structure.
|
||||
type User struct {
|
||||
Username string `json:"username"`
|
||||
Firstname string `json:"firstname"`
|
||||
Lastname string `json:"lastname"`
|
||||
City string `json:"city"`
|
||||
Age int `json:"age"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
app.Logger().SetLevel("debug")
|
||||
// app.Logger().SetLevel("disable") to disable the logger.
|
||||
|
||||
// Define templates using the std html/template engine.
|
||||
// Parse and load all files inside "./views" folder with ".html" file extension.
|
||||
// Reload the templates on each request (development mode).
|
||||
app.RegisterView(iris.HTML("./views", ".html").Reload(true))
|
||||
|
||||
// Register custom handler for specific http errors.
|
||||
app.OnErrorCode(iris.StatusInternalServerError, func(ctx iris.Context) {
|
||||
// .Values are used to communicate between handlers, middleware.
|
||||
errMessage := ctx.Values().GetString("error")
|
||||
if errMessage != "" {
|
||||
ctx.Writef("Internal server error: %s", errMessage)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Writef("(Unexpected) internal server error")
|
||||
})
|
||||
|
||||
app.Use(func(ctx iris.Context) {
|
||||
ctx.Application().Logger().Infof("Begin request for path: %s", ctx.Path())
|
||||
ctx.Next()
|
||||
})
|
||||
// app.Done(func(ctx iris.Context) {]})
|
||||
|
||||
// POST: scheme://mysubdomain.$domain.com/decode
|
||||
app.Subdomain("mysubdomain.").Post("/decode", func(ctx iris.Context) {})
|
||||
// Method POST: http://localhost:8080/decode
|
||||
app.Post("/decode", func(ctx iris.Context) {
|
||||
var user User
|
||||
ctx.ReadJSON(&user)
|
||||
ctx.Writef("%s %s is %d years old and comes from %s", user.Firstname, user.Lastname, user.Age, user.City)
|
||||
})
|
||||
|
||||
// Method GET: http://localhost:8080/encode
|
||||
app.Get("/encode", func(ctx iris.Context) {
|
||||
doe := User{
|
||||
Username: "Johndoe",
|
||||
Firstname: "John",
|
||||
Lastname: "Doe",
|
||||
City: "Neither FBI knows!!!",
|
||||
Age: 25,
|
||||
}
|
||||
|
||||
ctx.JSON(doe)
|
||||
})
|
||||
|
||||
// Method GET: http://localhost:8080/profile/anytypeofstring
|
||||
app.Get("/profile/{username:string}", profileByUsername)
|
||||
|
||||
usersRoutes := app.Party("/users", logThisMiddleware)
|
||||
{
|
||||
// Method GET: http://localhost:8080/users/42
|
||||
usersRoutes.Get("/{id:int min(1)}", getUserByID)
|
||||
// Method POST: http://localhost:8080/users/create
|
||||
usersRoutes.Post("/create", createUser)
|
||||
}
|
||||
|
||||
app.Get("/", func(ctx iris.Context) {
|
||||
ctx.HTML("<html><head></head><body><ul>")
|
||||
for _, link := range []string{"/encode", "/profile/username", "/users/42"} {
|
||||
ctx.HTML(`<li><a href="%s">%s</a></li>`, link, link)
|
||||
}
|
||||
ctx.HTML("</ul></body></html>")
|
||||
})
|
||||
|
||||
// Listen for incoming HTTP/1.x & HTTP/2 clients on localhost port 8080.
|
||||
app.Listen(":8080", iris.WithCharset("utf-8"))
|
||||
}
|
||||
|
||||
func logThisMiddleware(ctx iris.Context) {
|
||||
ctx.Application().Logger().Infof("Path: %s | IP: %s", ctx.Path(), ctx.RemoteAddr())
|
||||
|
||||
// .Next is required to move forward to the chain of handlers,
|
||||
// if missing then it stops the execution at this handler.
|
||||
ctx.Next()
|
||||
}
|
||||
|
||||
func profileByUsername(ctx iris.Context) {
|
||||
// .Params are used to get dynamic path parameters.
|
||||
username := ctx.Params().Get("username")
|
||||
ctx.ViewData("Username", username)
|
||||
// renders "./views/user/profile.html"
|
||||
// with {{ .Username }} equals to the username dynamic path parameter.
|
||||
ctx.View("user/profile.html")
|
||||
}
|
||||
|
||||
func getUserByID(ctx iris.Context) {
|
||||
userID := ctx.Params().Get("id") // Or convert directly using: .Values().GetInt/GetInt64 etc...
|
||||
// your own db fetch here instead of user :=...
|
||||
user := User{Username: "username" + userID}
|
||||
|
||||
ctx.XML(user)
|
||||
}
|
||||
|
||||
func createUser(ctx iris.Context) {
|
||||
var user User
|
||||
err := ctx.ReadForm(&user)
|
||||
if err != nil {
|
||||
ctx.Values().Set("error", "creating user, read and parse form failed. "+err.Error())
|
||||
ctx.StatusCode(iris.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
// renders "./views/user/create_verification.html"
|
||||
// with {{ . }} equals to the User object, i.e {{ .Username }} , {{ .Firstname}} etc...
|
||||
ctx.ViewData("", user)
|
||||
ctx.View("user/create_verification.html")
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<html>
|
||||
<head><title>Create verification</title></head>
|
||||
<body>
|
||||
<h1> Create Verification </h1>
|
||||
<table style="width:550px">
|
||||
<tr>
|
||||
<th>Username</th>
|
||||
<th>Firstname</th>
|
||||
<th>Lastname</th>
|
||||
<th>City</th>
|
||||
<th>Age</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ .Username }}</td>
|
||||
<td>{{ .Firstname }}</td>
|
||||
<td>{{ .Lastname }}</td>
|
||||
<td>{{ .City }}</td>
|
||||
<td>{{ .Age }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
7
_examples/routing/overview-2/views/user/profile.html
Normal file
7
_examples/routing/overview-2/views/user/profile.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<head><title>Profile page</title></head>
|
||||
<body>
|
||||
<h1> Profile </h1>
|
||||
<b> {{ .Username }} </b>
|
||||
</body>
|
||||
</html>
|
||||
@@ -107,7 +107,7 @@ func main() {
|
||||
|
||||
// Subdomains, depends on the host, you have to edit the hosts or nginx/caddy's configuration if you use them.
|
||||
//
|
||||
// See more subdomains examples at _examples/subdomains folder.
|
||||
// See more subdomains examples at _examples/routing/subdomains folder.
|
||||
adminRoutes := app.Party("admin.")
|
||||
|
||||
// GET: http://admin.localhost:8080
|
||||
|
||||
38
_examples/routing/sitemap/main.go
Normal file
38
_examples/routing/sitemap/main.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/kataras/iris/v12"
|
||||
)
|
||||
|
||||
const startURL = "http://localhost:8080"
|
||||
|
||||
func main() {
|
||||
app := newApp()
|
||||
|
||||
// http://localhost:8080/sitemap.xml
|
||||
// Lists only online GET static routes.
|
||||
//
|
||||
// Reference: https://www.sitemaps.org/protocol.html
|
||||
app.Listen(":8080", iris.WithSitemap(startURL))
|
||||
}
|
||||
|
||||
func newApp() *iris.Application {
|
||||
app := iris.New()
|
||||
app.Logger().SetLevel("debug")
|
||||
|
||||
lastModified, _ := time.Parse("2006-01-02T15:04:05-07:00", "2019-12-13T21:50:33+02:00")
|
||||
app.Get("/home", handler).SetLastMod(lastModified).SetChangeFreq("hourly").SetPriority(1)
|
||||
app.Get("/articles", handler).SetChangeFreq("daily")
|
||||
app.Get("/path1", handler)
|
||||
app.Get("/path2", handler)
|
||||
|
||||
app.Post("/this-should-not-be-listed", handler)
|
||||
app.Get("/this/{myparam}/should/not/be/listed", handler)
|
||||
app.Get("/this-should-not-be-listed-offline", handler).SetStatusOffline()
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
func handler(ctx iris.Context) { ctx.WriteString(ctx.Path()) }
|
||||
18
_examples/routing/sitemap/main_test.go
Normal file
18
_examples/routing/sitemap/main_test.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/kataras/iris/v12"
|
||||
"github.com/kataras/iris/v12/httptest"
|
||||
)
|
||||
|
||||
func TestSitemap(t *testing.T) {
|
||||
const expectedFullSitemapXML = `<?xml version="1.0" encoding="utf-8" standalone="yes"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><url><loc>http://localhost:8080/home</loc><lastmod>2019-12-13T21:50:33+02:00</lastmod><changefreq>hourly</changefreq><priority>1</priority></url><url><loc>http://localhost:8080/articles</loc><changefreq>daily</changefreq></url><url><loc>http://localhost:8080/path1</loc></url><url><loc>http://localhost:8080/path2</loc></url></urlset>`
|
||||
|
||||
app := newApp()
|
||||
app.Configure(iris.WithSitemap(startURL))
|
||||
|
||||
e := httptest.New(t, app)
|
||||
e.GET("/sitemap.xml").Expect().Status(httptest.StatusOK).Body().Equal(expectedFullSitemapXML)
|
||||
}
|
||||
28
_examples/routing/subdomains/multi/hosts
Normal file
28
_examples/routing/subdomains/multi/hosts
Normal file
@@ -0,0 +1,28 @@
|
||||
# Copyright (c) 1993-2009 Microsoft Corp.
|
||||
#
|
||||
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
|
||||
#
|
||||
# This file contains the mappings of IP addresses to host names. Each
|
||||
# entry should be kept on an individual line. The IP address should
|
||||
# be placed in the first column followed by the corresponding host name.
|
||||
# The IP address and the host name should be separated by at least one
|
||||
# space.
|
||||
#
|
||||
# Additionally, comments (such as these) may be inserted on individual
|
||||
# lines or following the machine name denoted by a '#' symbol.
|
||||
#
|
||||
# For example:
|
||||
#
|
||||
# 102.54.94.97 rhino.acme.com # source server
|
||||
# 38.25.63.10 x.acme.com # x client host
|
||||
|
||||
# localhost name resolution is handled within DNS itself.
|
||||
127.0.0.1 localhost
|
||||
::1 localhost
|
||||
#-iris-For development machine, you have to configure your dns also for online, search google how to do it if you don't know
|
||||
|
||||
127.0.0.1 domain.local
|
||||
127.0.0.1 system.domain.local
|
||||
127.0.0.1 dashboard.domain.local
|
||||
|
||||
#-END iris-
|
||||
40
_examples/routing/subdomains/multi/main.go
Normal file
40
_examples/routing/subdomains/multi/main.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/v12"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
|
||||
/*
|
||||
* Setup static files
|
||||
*/
|
||||
|
||||
app.HandleDir("/assets", "./public/assets")
|
||||
app.HandleDir("/upload_resources", "./public/upload_resources")
|
||||
|
||||
dashboard := app.Party("dashboard.")
|
||||
{
|
||||
dashboard.Get("/", func(ctx iris.Context) {
|
||||
ctx.Writef("HEY FROM dashboard")
|
||||
})
|
||||
}
|
||||
system := app.Party("system.")
|
||||
{
|
||||
system.Get("/", func(ctx iris.Context) {
|
||||
ctx.Writef("HEY FROM system")
|
||||
})
|
||||
}
|
||||
|
||||
app.Get("/", func(ctx iris.Context) {
|
||||
ctx.Writef("HEY FROM frontend /")
|
||||
})
|
||||
// http://domain.local:80
|
||||
// http://dashboard.local
|
||||
// http://system.local
|
||||
// Make sure you prepend the "http" in your browser
|
||||
// because .local is a virtual domain we think to show case you
|
||||
// that you can declare any syntactical correct name as a subdomain in iris.
|
||||
app.Listen("domain.local:80") // for beginners: look ../hosts file
|
||||
}
|
||||
BIN
_examples/routing/subdomains/multi/public/assets/images/test.ico
Normal file
BIN
_examples/routing/subdomains/multi/public/assets/images/test.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
4
_examples/routing/subdomains/redirect/hosts
Normal file
4
_examples/routing/subdomains/redirect/hosts
Normal file
@@ -0,0 +1,4 @@
|
||||
127.0.0.1 mydomain.com
|
||||
127.0.0.1 www.mydomain.com
|
||||
|
||||
# Windows: Drive:/Windows/system32/drivers/etc/hosts, on Linux: /etc/hosts
|
||||
73
_examples/routing/subdomains/redirect/main.go
Normal file
73
_examples/routing/subdomains/redirect/main.go
Normal file
@@ -0,0 +1,73 @@
|
||||
// Package main shows how to register a simple 'www' subdomain,
|
||||
// using the `app.WWW` method, which will register a router wrapper which will
|
||||
// redirect all 'mydomain.com' requests to 'www.mydomain.com'.
|
||||
// Check the 'hosts' file to see how to test the 'mydomain.com' on your local machine.
|
||||
package main
|
||||
|
||||
import "github.com/kataras/iris/v12"
|
||||
|
||||
const addr = "mydomain.com:80"
|
||||
|
||||
func main() {
|
||||
app := newApp()
|
||||
|
||||
// http(s)://mydomain.com, will be redirect to http(s)://www.mydomain.com.
|
||||
// The `www` variable is the `app.Subdomain("www")`.
|
||||
//
|
||||
// app.WWW() wraps the router so it can redirect all incoming requests
|
||||
// that comes from 'http(s)://mydomain.com/%path%' (www is missing)
|
||||
// to `http(s)://www.mydomain.com/%path%`.
|
||||
//
|
||||
// Try:
|
||||
// http://mydomain.com -> http://www.mydomain.com
|
||||
// http://mydomain.com/users -> http://www.mydomain.com/users
|
||||
// http://mydomain.com/users/login -> http://www.mydomain.com/users/login
|
||||
app.Listen(addr)
|
||||
}
|
||||
|
||||
func newApp() *iris.Application {
|
||||
app := iris.New()
|
||||
app.Get("/", func(ctx iris.Context) {
|
||||
ctx.Writef("This will never be executed.")
|
||||
})
|
||||
|
||||
www := app.Subdomain("www") // <- same as app.Party("www.")
|
||||
www.Get("/", index)
|
||||
|
||||
// www is an `iris.Party`, use it like you already know, like grouping routes.
|
||||
www.PartyFunc("/users", func(p iris.Party) { // <- same as www.Party("/users").Get(...)
|
||||
p.Get("/", usersIndex)
|
||||
p.Get("/login", getLogin)
|
||||
})
|
||||
|
||||
// redirects mydomain.com/%anypath% to www.mydomain.com/%anypath%.
|
||||
// First argument is the 'from' and second is the 'to/target'.
|
||||
app.SubdomainRedirect(app, www)
|
||||
|
||||
// SubdomainRedirect works for multi-level subdomains as well:
|
||||
// subsub := www.Subdomain("subsub") // subsub.www.mydomain.com
|
||||
// subsub.Get("/", func(ctx iris.Context) { ctx.Writef("subdomain is: " + ctx.Subdomain()) })
|
||||
// app.SubdomainRedirect(subsub, www)
|
||||
//
|
||||
// If you need to redirect any subdomain to 'www' then:
|
||||
// app.SubdomainRedirect(app.WildcardSubdomain(), www)
|
||||
// If you need to redirect from a subdomain to the root domain then:
|
||||
// app.SubdomainRedirect(app.Subdomain("mysubdomain"), app)
|
||||
//
|
||||
// Note that app.Party("mysubdomain.") and app.Subdomain("mysubdomain")
|
||||
// is the same exactly thing, the difference is that the second can omit the last dot('.').
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
func index(ctx iris.Context) {
|
||||
ctx.Writef("This is the www.mydomain.com endpoint.")
|
||||
}
|
||||
|
||||
func usersIndex(ctx iris.Context) {
|
||||
ctx.Writef("This is the www.mydomain.com/users endpoint.")
|
||||
}
|
||||
|
||||
func getLogin(ctx iris.Context) {
|
||||
ctx.Writef("This is the www.mydomain.com/users/login endpoint.")
|
||||
}
|
||||
29
_examples/routing/subdomains/redirect/main_test.go
Normal file
29
_examples/routing/subdomains/redirect/main_test.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/kataras/iris/v12/httptest"
|
||||
)
|
||||
|
||||
func TestSubdomainRedirectWWW(t *testing.T) {
|
||||
app := newApp()
|
||||
root := strings.TrimSuffix(addr, ":80")
|
||||
|
||||
e := httptest.New(t, app)
|
||||
|
||||
tests := []struct {
|
||||
path string
|
||||
response string
|
||||
}{
|
||||
{"/", fmt.Sprintf("This is the www.%s endpoint.", root)},
|
||||
{"/users", fmt.Sprintf("This is the www.%s/users endpoint.", root)},
|
||||
{"/users/login", fmt.Sprintf("This is the www.%s/users/login endpoint.", root)},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
e.GET(test.path).Expect().Status(httptest.StatusOK).Body().Equal(test.response)
|
||||
}
|
||||
}
|
||||
27
_examples/routing/subdomains/single/hosts
Normal file
27
_examples/routing/subdomains/single/hosts
Normal file
@@ -0,0 +1,27 @@
|
||||
# Copyright (c) 1993-2009 Microsoft Corp.
|
||||
#
|
||||
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
|
||||
#
|
||||
# This file contains the mappings of IP addresses to host names. Each
|
||||
# entry should be kept on an individual line. The IP address should
|
||||
# be placed in the first column followed by the corresponding host name.
|
||||
# The IP address and the host name should be separated by at least one
|
||||
# space.
|
||||
#
|
||||
# Additionally, comments (such as these) may be inserted on individual
|
||||
# lines or following the machine name denoted by a '#' symbol.
|
||||
#
|
||||
# For example:
|
||||
#
|
||||
# 102.54.94.97 rhino.acme.com # source server
|
||||
# 38.25.63.10 x.acme.com # x client host
|
||||
|
||||
# localhost name resolution is handled within DNS itself.
|
||||
127.0.0.1 localhost
|
||||
::1 localhost
|
||||
#-iris-For development machine, you have to configure your dns also for online, search google how to do it if you don't know
|
||||
|
||||
127.0.0.1 mydomain.com
|
||||
127.0.0.1 admin.mydomain.com
|
||||
|
||||
#-END iris-
|
||||
44
_examples/routing/subdomains/single/main.go
Normal file
44
_examples/routing/subdomains/single/main.go
Normal file
@@ -0,0 +1,44 @@
|
||||
// Package main register static subdomains, simple as parties, check ./hosts if you use windows
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/v12"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
|
||||
// Subdomain method is just another Party.
|
||||
admin := app.Subdomain("admin")
|
||||
{
|
||||
// admin.mydomain.com
|
||||
admin.Get("/", func(c iris.Context) {
|
||||
c.Writef("INDEX FROM admin.mydomain.com")
|
||||
})
|
||||
// admin.mydomain.com/hey
|
||||
admin.Get("/hey", func(c iris.Context) {
|
||||
c.Writef("HEY FROM admin.mydomain.com/hey")
|
||||
})
|
||||
// admin.mydomain.com/hey2
|
||||
admin.Get("/hey2", func(c iris.Context) {
|
||||
c.Writef("HEY SECOND FROM admin.mydomain.com/hey")
|
||||
})
|
||||
}
|
||||
|
||||
// mydomain.com
|
||||
app.Get("/", func(c iris.Context) {
|
||||
c.Writef("INDEX FROM no-subdomain hey")
|
||||
})
|
||||
|
||||
// mydomain.com/hey
|
||||
app.Get("/hey", func(c iris.Context) {
|
||||
c.Writef("HEY FROM no-subdomain hey")
|
||||
})
|
||||
|
||||
// http://admin.mydomain.com
|
||||
// http://admin.mydomain.com/hey
|
||||
// http://admin.mydomain.com/hey2
|
||||
// http://mydomain.com
|
||||
// http://mydomain.com/hey
|
||||
app.Listen("mydomain.com:80") // for beginners: look ../hosts file
|
||||
}
|
||||
30
_examples/routing/subdomains/wildcard/hosts
Normal file
30
_examples/routing/subdomains/wildcard/hosts
Normal file
@@ -0,0 +1,30 @@
|
||||
# Copyright (c) 1993-2009 Microsoft Corp.
|
||||
#
|
||||
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
|
||||
#
|
||||
# This file contains the mappings of IP addresses to host names. Each
|
||||
# entry should be kept on an individual line. The IP address should
|
||||
# be placed in the first column followed by the corresponding host name.
|
||||
# The IP address and the host name should be separated by at least one
|
||||
# space.
|
||||
#
|
||||
# Additionally, comments (such as these) may be inserted on individual
|
||||
# lines or following the machine name denoted by a '#' symbol.
|
||||
#
|
||||
# For example:
|
||||
#
|
||||
# 102.54.94.97 rhino.acme.com # source server
|
||||
# 38.25.63.10 x.acme.com # x client host
|
||||
|
||||
# localhost name resolution is handled within DNS itself.
|
||||
127.0.0.1 localhost
|
||||
::1 localhost
|
||||
#-iris-For development machine, you have to configure your dns also for online, search google how to do it if you don't know
|
||||
127.0.0.1 mydomain.com
|
||||
127.0.0.1 username1.mydomain.com
|
||||
127.0.0.1 username2.mydomain.com
|
||||
127.0.0.1 username3.mydomain.com
|
||||
127.0.0.1 username4.mydomain.com
|
||||
127.0.0.1 username5.mydomain.com
|
||||
|
||||
#-END iris-
|
||||
71
_examples/routing/subdomains/wildcard/main.go
Normal file
71
_examples/routing/subdomains/wildcard/main.go
Normal file
@@ -0,0 +1,71 @@
|
||||
// Package main an example on how to catch dynamic subdomains - wildcard.
|
||||
// On the first example we learnt how to create routes for static subdomains, subdomains you know that you will have.
|
||||
// Here we will see an example how to catch unknown subdomains, dynamic subdomains, like username.mydomain.com:8080.
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/v12"
|
||||
)
|
||||
|
||||
// register a dynamic-wildcard subdomain to your server machine(dns/...) first, check ./hosts if you use windows.
|
||||
// run this file and try to redirect: http://username1.mydomain.com:8080/ , http://username2.mydomain.com:8080/ , http://username1.mydomain.com/something, http://username1.mydomain.com/something/sadsadsa
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
|
||||
/* Keep note that you can use both type of subdomains (named and wildcard(*.) )
|
||||
admin.mydomain.com, and for other the Party(*.) but this is not this example's purpose
|
||||
|
||||
admin := app.Party("admin.")
|
||||
{
|
||||
// admin.mydomain.com
|
||||
admin.Get("/", func(ctx iris.Context) {
|
||||
ctx.Writef("INDEX FROM admin.mydomain.com")
|
||||
})
|
||||
// admin.mydomain.com/hey
|
||||
admin.Get("/hey", func(ctx iris.Context) {
|
||||
ctx.Writef("HEY FROM admin.mydomain.com/hey")
|
||||
})
|
||||
// admin.mydomain.com/hey2
|
||||
admin.Get("/hey2", func(ctx iris.Context) {
|
||||
ctx.Writef("HEY SECOND FROM admin.mydomain.com/hey")
|
||||
})
|
||||
}*/
|
||||
|
||||
// no order, you can register subdomains at the end also.
|
||||
dynamicSubdomains := app.Party("*.")
|
||||
{
|
||||
dynamicSubdomains.Get("/", dynamicSubdomainHandler)
|
||||
|
||||
dynamicSubdomains.Get("/something", dynamicSubdomainHandler)
|
||||
|
||||
dynamicSubdomains.Get("/something/{paramfirst}", dynamicSubdomainHandlerWithParam)
|
||||
}
|
||||
|
||||
app.Get("/", func(ctx iris.Context) {
|
||||
ctx.Writef("Hello from mydomain.com path: %s", ctx.Path())
|
||||
})
|
||||
|
||||
app.Get("/hello", func(ctx iris.Context) {
|
||||
ctx.Writef("Hello from mydomain.com path: %s", ctx.Path())
|
||||
})
|
||||
|
||||
// http://mydomain.com:8080
|
||||
// http://username1.mydomain.com:8080
|
||||
// http://username2.mydomain.com:8080/something
|
||||
// http://username3.mydomain.com:8080/something/yourname
|
||||
app.Listen("mydomain.com:8080") // for beginners: look ../hosts file
|
||||
}
|
||||
|
||||
func dynamicSubdomainHandler(ctx iris.Context) {
|
||||
username := ctx.Subdomain()
|
||||
ctx.Writef("Hello from dynamic subdomain path: %s, here you can handle the route for dynamic subdomains, handle the user: %s", ctx.Path(), username)
|
||||
// if http://username4.mydomain.com:8080/ prints:
|
||||
// Hello from dynamic subdomain path: /, here you can handle the route for dynamic subdomains, handle the user: username4
|
||||
}
|
||||
|
||||
func dynamicSubdomainHandlerWithParam(ctx iris.Context) {
|
||||
username := ctx.Subdomain()
|
||||
ctx.Writef("Hello from dynamic subdomain path: %s, here you can handle the route for dynamic subdomains, handle the user: %s", ctx.Path(), username)
|
||||
ctx.Writef("The paramfirst is: %s", ctx.Params().Get("paramfirst"))
|
||||
}
|
||||
25
_examples/routing/subdomains/www/hosts
Normal file
25
_examples/routing/subdomains/www/hosts
Normal file
@@ -0,0 +1,25 @@
|
||||
# Copyright (c) 1993-2009 Microsoft Corp.
|
||||
#
|
||||
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
|
||||
#
|
||||
# This file contains the mappings of IP addresses to host names. Each
|
||||
# entry should be kept on an individual line. The IP address should
|
||||
# be placed in the first column followed by the corresponding host name.
|
||||
# The IP address and the host name should be separated by at least one
|
||||
# space.
|
||||
#
|
||||
# Additionally, comments (such as these) may be inserted on individual
|
||||
# lines or following the machine name denoted by a '#' symbol.
|
||||
#
|
||||
# For example:
|
||||
#
|
||||
# 102.54.94.97 rhino.acme.com # source server
|
||||
# 38.25.63.10 x.acme.com # x client host
|
||||
|
||||
# localhost name resolution is handled within DNS itself.
|
||||
127.0.0.1 localhost
|
||||
::1 localhost
|
||||
#-iris-For development machine, you have to configure your dns also for online, search google how to do it if you don't know
|
||||
127.0.0.1 mydomain.com
|
||||
127.0.0.1 www.mydomain.com
|
||||
#-END iris-
|
||||
79
_examples/routing/subdomains/www/main.go
Normal file
79
_examples/routing/subdomains/www/main.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/v12"
|
||||
)
|
||||
|
||||
func newApp() *iris.Application {
|
||||
app := iris.New()
|
||||
|
||||
app.Get("/", info)
|
||||
app.Get("/about", info)
|
||||
app.Get("/contact", info)
|
||||
|
||||
app.PartyFunc("/api/users", func(r iris.Party) {
|
||||
r.Get("/", info)
|
||||
r.Get("/{id:uint64}", info)
|
||||
|
||||
r.Post("/", info)
|
||||
|
||||
r.Put("/{id:uint64}", info)
|
||||
}) /* <- same as:
|
||||
usersAPI := app.Party("/api/users")
|
||||
{ // those brackets are just syntactic-sugar things.
|
||||
// This method is rarely used but you can make use of it when you want
|
||||
// scoped variables to that code block only.
|
||||
usersAPI.Get/Post...
|
||||
}
|
||||
usersAPI.Get/Post...
|
||||
*/
|
||||
|
||||
www := app.Party("www.")
|
||||
{
|
||||
// Just to show how you can get all routes and copy them to another
|
||||
// party or subdomain:
|
||||
// Get all routes that are registered so far, including all "Parties" and subdomains:
|
||||
currentRoutes := app.GetRoutes()
|
||||
// Register them to the www subdomain/vhost as well:
|
||||
for _, r := range currentRoutes {
|
||||
www.Handle(r.Method, r.Tmpl().Src, r.Handlers...)
|
||||
}
|
||||
|
||||
// http://www.mydomain.com/hi
|
||||
www.Get("/hi", func(ctx iris.Context) {
|
||||
ctx.Writef("hi from www.mydomain.com")
|
||||
})
|
||||
}
|
||||
// See also the "subdomains/redirect" to register redirect router wrappers between subdomains,
|
||||
// i.e mydomain.com to www.mydomain.com (like facebook does for SEO reasons(;)).
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := newApp()
|
||||
// http://mydomain.com
|
||||
// http://mydomain.com/about
|
||||
// http://imydomain.com/contact
|
||||
// http://mydomain.com/api/users
|
||||
// http://mydomain.com/api/users/42
|
||||
|
||||
// http://www.mydomain.com
|
||||
// http://www.mydomain.com/hi
|
||||
// http://www.mydomain.com/about
|
||||
// http://www.mydomain.com/contact
|
||||
// http://www.mydomain.com/api/users
|
||||
// http://www.mydomain.com/api/users/42
|
||||
if err := app.Listen("mydomain.com:80"); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func info(ctx iris.Context) {
|
||||
method := ctx.Method()
|
||||
subdomain := ctx.Subdomain()
|
||||
path := ctx.Path()
|
||||
|
||||
ctx.Writef("\nInfo\n\n")
|
||||
ctx.Writef("Method: %s\nSubdomain: %s\nPath: %s", method, subdomain, path)
|
||||
}
|
||||
57
_examples/routing/subdomains/www/main_test.go
Normal file
57
_examples/routing/subdomains/www/main_test.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/kataras/iris/v12/httptest"
|
||||
)
|
||||
|
||||
type testRoute struct {
|
||||
path string
|
||||
method string
|
||||
subdomain string
|
||||
}
|
||||
|
||||
func (r testRoute) response() string {
|
||||
msg := fmt.Sprintf("\nInfo\n\nMethod: %s\nSubdomain: %s\nPath: %s", r.method, r.subdomain, r.path)
|
||||
return msg
|
||||
}
|
||||
|
||||
func TestSubdomainWWW(t *testing.T) {
|
||||
app := newApp()
|
||||
|
||||
tests := []testRoute{
|
||||
// host
|
||||
{"/", "GET", ""},
|
||||
{"/about", "GET", ""},
|
||||
{"/contact", "GET", ""},
|
||||
{"/api/users", "GET", ""},
|
||||
{"/api/users/42", "GET", ""},
|
||||
{"/api/users", "POST", ""},
|
||||
{"/api/users/42", "PUT", ""},
|
||||
// www sub domain
|
||||
{"/", "GET", "www"},
|
||||
{"/about", "GET", "www"},
|
||||
{"/contact", "GET", "www"},
|
||||
{"/api/users", "GET", "www"},
|
||||
{"/api/users/42", "GET", "www"},
|
||||
{"/api/users", "POST", "www"},
|
||||
{"/api/users/42", "PUT", "www"},
|
||||
}
|
||||
|
||||
host := "localhost:1111"
|
||||
e := httptest.New(t, app, httptest.Debug(false))
|
||||
|
||||
for _, test := range tests {
|
||||
|
||||
req := e.Request(test.method, test.path)
|
||||
if subdomain := test.subdomain; subdomain != "" {
|
||||
req.WithURL("http://" + subdomain + "." + host)
|
||||
}
|
||||
|
||||
req.Expect().
|
||||
Status(httptest.StatusOK).
|
||||
Body().Equal(test.response())
|
||||
}
|
||||
}
|
||||
73
_examples/routing/versioning/main.go
Normal file
73
_examples/routing/versioning/main.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/v12"
|
||||
"github.com/kataras/iris/v12/versioning"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
|
||||
examplePerRoute(app)
|
||||
examplePerParty(app)
|
||||
|
||||
// Read the README.md before any action.
|
||||
app.Listen(":8080")
|
||||
}
|
||||
|
||||
// How to test:
|
||||
// Open Postman
|
||||
// GET: localhost:8080/api/cats
|
||||
// Headers[1] = Accept-Version: "1" and repeat with
|
||||
// Headers[1] = Accept-Version: "2.5"
|
||||
// or even "Accept": "application/json; version=2.5"
|
||||
func examplePerRoute(app *iris.Application) {
|
||||
app.Get("/api/cats", versioning.NewMatcher(versioning.Map{
|
||||
"1": catsVersionExactly1Handler,
|
||||
">= 2, < 3": catsV2Handler,
|
||||
versioning.NotFound: versioning.NotFoundHandler,
|
||||
}))
|
||||
}
|
||||
|
||||
// How to test:
|
||||
// Open Postman
|
||||
// GET: localhost:8080/api/users
|
||||
// Headers[1] = Accept-Version: "1.9.9" and repeat with
|
||||
// Headers[1] = Accept-Version: "2.5"
|
||||
//
|
||||
// POST: localhost:8080/api/users/new
|
||||
// Headers[1] = Accept-Version: "1.8.3"
|
||||
//
|
||||
// POST: localhost:8080/api/users
|
||||
// Headers[1] = Accept-Version: "2"
|
||||
func examplePerParty(app *iris.Application) {
|
||||
usersAPI := app.Party("/api/users")
|
||||
|
||||
// version 1.
|
||||
usersAPIV1 := versioning.NewGroup(">= 1, < 2")
|
||||
usersAPIV1.Get("/", func(ctx iris.Context) {
|
||||
ctx.Writef("v1 resource: /api/users handler")
|
||||
})
|
||||
usersAPIV1.Post("/new", func(ctx iris.Context) {
|
||||
ctx.Writef("v1 resource: /api/users/new post handler")
|
||||
})
|
||||
|
||||
// version 2.
|
||||
usersAPIV2 := versioning.NewGroup(">= 2, < 3")
|
||||
usersAPIV2.Get("/", func(ctx iris.Context) {
|
||||
ctx.Writef("v2 resource: /api/users handler")
|
||||
})
|
||||
usersAPIV2.Post("/", func(ctx iris.Context) {
|
||||
ctx.Writef("v2 resource: /api/users post handler")
|
||||
})
|
||||
|
||||
versioning.RegisterGroups(usersAPI, versioning.NotFoundHandler, usersAPIV1, usersAPIV2)
|
||||
}
|
||||
|
||||
func catsVersionExactly1Handler(ctx iris.Context) {
|
||||
ctx.Writef("v1 exactly resource: /api/cats handler")
|
||||
}
|
||||
|
||||
func catsV2Handler(ctx iris.Context) {
|
||||
ctx.Writef("v2 resource: /api/cats handler")
|
||||
}
|
||||
Reference in New Issue
Block a user