1
0
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:
Gerasimos (Makis) Maropoulos
2020-06-07 15:26:06 +03:00
parent 9fdcb4c7fb
commit ed45c77be5
328 changed files with 4262 additions and 41621 deletions

View File

@@ -0,0 +1,3 @@
.git
node_modules
bin

View 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"]

View 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
```

View File

@@ -0,0 +1,8 @@
# docker-compose up [--build]
version: '3'
services:
app:
build: .
ports:
- 8080:8080

View File

@@ -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>`)
})

View File

@@ -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

View 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")
}

View 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")
}

View File

@@ -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>

View File

@@ -0,0 +1,7 @@
<html>
<head><title>Profile page</title></head>
<body>
<h1> Profile </h1>
<b> {{ .Username }} </b>
</body>
</html>

View File

@@ -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

View 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()) }

View 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)
}

View 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-

View 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
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View 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

View 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.")
}

View 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)
}
}

View 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-

View 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
}

View 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-

View 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"))
}

View 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-

View 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)
}

View 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())
}
}

View 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")
}