The fastest HTTP/2 Go Web Framework. AWS Lambda, gRPC, MVC, Unique Router, Websockets, Sessions, Test suite, Dependency Injection and more. A true successor of expressjs and laravel | 谢谢 https://github.com/kataras/iris/issues/1329 |

Black Lives Matter

News

This is the under-development branch. Stay tuned for the upcoming release v12.2.0. Looking for a stable release? Head over to the v12.1.8 branch instead.

Try the official Iris Command Line Interface today!

Due to the large workload, there may be delays in answering your questions.

Iris Web Framework

build status view examples chat donate

Iris is a fast, simple yet fully featured and very efficient web framework for Go.

It provides a beautifully expressive and easy to use foundation for your next website or API.

Simple Handler
package main

import "github.com/kataras/iris/v12"

type (
  request struct {
    Firstname string `json:"firstname"`
    Lastname  string `json:"lastname"`
  }

  response struct {
    ID      uint64 `json:"id"`
    Message string `json:"message"`
  }
)

func main() {
  app := iris.New()
  app.Handle("PUT", "/users/{id:uint64}", updateUser)
  app.Listen(":8080")
}

func updateUser(ctx iris.Context) {
  id, _ := ctx.Params().GetUint64("id")

  var req request
  if err := ctx.ReadJSON(&req); err != nil {
    ctx.StopWithError(iris.StatusBadRequest, err)
    return
  }

  resp := response{
    ID:      id,
    Message: req.Firstname + " updated successfully",
  }
  ctx.JSON(resp)
}

Read the routing examples for more!

Handler with custom input and output arguments

https://github.com/kataras/iris/blob/master/_examples/dependency-injection/basic/main.go

Interesting? Read the examples.

MVC
package main

import (
  "github.com/kataras/iris/v12"
  "github.com/kataras/iris/v12/mvc"
)

type (
  request struct {
    Firstname string `json:"firstname"`
    Lastname  string `json:"lastname"`
  }

  response struct {
    ID      uint64 `json:"id"`
    Message string `json:"message"`
  }
)

func main() {
  app := iris.New()
  mvc.Configure(app.Party("/users"), configureMVC)
  app.Listen(":8080")
}

func configureMVC(app *mvc.Application) {
  app.Handle(new(userController))
}

type userController struct {
  // [...dependencies]
}

func (c *userController) PutBy(id uint64, req request) response {
  return response{
    ID:      id,
    Message: req.Firstname + " updated successfully",
  }
}

Want to see more? Navigate through mvc examples!

Learn what others saying about Iris and star this open-source project to support its potentials.

Benchmarks: Jul 18, 2020 at 10:46am (UTC)

👑 Supporters

With your help, we can improve Open Source web development for everyone!

Donations from China are now accepted!

George Fourikis Александр Лебединский Li Yang Qianyu Zhou anilpdv CAO HOAI BAO Oscar Hernandez Gerard Lancea neulhan xushiquan Matt Ľuboš Pinteš Leighton McKeen Weliam simranjit singh Kenneth Jordan Morlé Koudeka Rui Carlos Augusto Horst Ender Pavithran MULYAWAN SENTOSA KIT UNITED Ricardo Hernandez Lopez ChinChuanKuo Nikhar Saxena Servio Zambrano Nate Anderson Claude Muller Marco Moeser Sanketh P B Vu Hoang Lam Dimitar Trifonov Midhubalan Balasubramanian AANAND NATARAJAN Edsongley Almeida ganben Tejus Pratap cui hexiang tinawang Juan David Parra Pimiento Andy Chong Ying Zhi Kevin Zhou Jasper Simranjit Singh Christopher Lamm 叶峻峣 TSAI LI TING zhutao George Alexiou Jobert Azares Tam Nguyen 
Venkatt Guhesan Anibal C C Budaye ARAN ROKA Valentine Chakravarthy Raghunandan Massimiliano Bertinetti Hieu Trinh J.T. Feng Gabor Lekeny LiHaotian Muyang Li Hao Tu Cetin Basoz Hazmi Amalul Rémy Deme Vincent Li Max Trense Matej Lach Joseph De Paola Damon Blais 陆 轶丰 Weihang Ding Li Fang TechMaster lenses.io Celso Souza Altafino Thomas Fritz Conrad Steenberg Damon Zhao George Opritescu Juanses Ankur Srivastava Lex Tang li3p

📖 Learning Iris

Create a new project

$ mkdir myapp
$ cd myapp
$ go mod init myapp
$ go get github.com/kataras/iris/v12@master # or @v12.2.0-alpha2
Install on existing project
$ cd myapp
$ go get github.com/kataras/iris/v12@master
Install with a go.mod file
module myapp

go 1.16

require github.com/kataras/iris/v12 master

Run

$ go mod download
$ go run main.go
# OR just:
# go run -mod=mod main.go

Iris contains extensive and thorough documentation making it easy to get started with the framework.

For a more detailed technical documentation you can head over to our godocs. And for executable code you can always visit the ./_examples repository's subdirectory.

Do you like to read while traveling?

Book cover

follow author on twitter

follow Iris web framework on twitter

follow Iris web framework on facebook

You can request a PDF and online access of the Iris E-Book (New Edition, future v12.2.0+) today and be participated in the development of Iris.

🙌 Contributing

We'd love to see your contribution to the Iris Web Framework! For more information about contributing to the Iris project please check the CONTRIBUTING.md file.

List of all Contributors

🛡 Security Vulnerabilities

If you discover a security vulnerability within Iris, please send an e-mail to [email protected]. All security vulnerabilities will be promptly addressed.

📝 License

This project is licensed under the BSD 3-clause license, just like the Go project itself.

The project name "Iris" was inspired by the Greek mythology.

Owner
Gerasimos (Makis) Maropoulos
🥇 That Greek Gopher | 💨 Senior Backend Engineer at PNOĒ | 🎓My dream is to create an international IT university that will produce flawless developers!
Gerasimos (Makis) Maropoulos
Comments
  • [QUESTION]can logger write to multiple files asynchronously and rotate based on size or time?

    [QUESTION]can logger write to multiple files asynchronously and rotate based on size or time?

    I need to write different level to different file for example: INFO & WARN level write toinfo.log ERRO level write to error.log In addition, I need to save the access log including request params and response data to access.log

    If the log files become more and more large, I expect that logger can automatically rotate the log files based on size or time

    Does logger support the requirements above and write file asynchronously?

  • [DOCUMENTATION] No Content-Encoding: gzip header on gzip-ed bindata

    [DOCUMENTATION] No Content-Encoding: gzip header on gzip-ed bindata

    Describe the bug I use kataras/bindata to embeding some files, but iris reponse without Content-Encoding: gzip header

    To Reproduce

    go get -u github.com/kataras/bindata/cmd/bindata
    bindata ./public/...
    go build
    
    	app.HandleDir("/static", "./public", iris.DirOptions{
    		Asset:      GzipAsset,
    		AssetInfo:  GzipAssetInfo,
    		AssetNames: GzipAssetNames,
    	})
    

    The public dir has only one file index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>NMac Mirror</title>
    </head>
    <body>
    Hello!
    </body>
    </html>
    

    Screenshots image

    Desktop MacOS 10.14.6

  • websocket rebuild 2019

    websocket rebuild 2019

    i have got the mel formed json from the websocket output. Currently found out that is caused by some race detection from the data transmission. it is the same issue caused by unsafe access in ByteBuffer.

  • Ability to customize Logrus

    Ability to customize Logrus

    Logrus is a popular logging package. Some already use this in their projects, and set it up with Console in dev and JSON writers in production. It would be nice to add the ability to customize Logrus inside of Iris. I propose and could easily add the ability to set the Logrus object to use. Even better, would be nice to have it's own context.

  • [BUG] CORS doesn't support Subdomains

    [BUG] CORS doesn't support Subdomains

    Summary

    I attempted to host my assets directory as a Subdomain, which Chrome complained requires CORS. So, I followed the example code within the repository (which, btw, doesn't work on a Party, but only on the entire server, so is incompatible with subdomains), and found that it doesn't work at all.

    Screenshot

    image

    Versions, etc.

    |Thing|Version| |-|-| |Golang|1.14.6 linux/amd64| |Iris|master d0d7679| |Kernel|5.7.14-200.fc32.x86_64| |OS|Fedora 32 Workstation|

    Sample Code

    	c := cors.New(cors.Options{
    		AllowedOrigins: []string{
    			*domain,
    			fmt.Sprintf("www.%s", *domain),
    			fmt.Sprintf("your.%s", *domain),
    		},
    		AllowCredentials: true,
    	})
    	app.WrapRouter(c.ServeHTTP)
    
    	// define subdomain "your."
    	your := app.Subdomain("your")
    	your.Use(requestid.New())
    
    	// host the ./public directory as subdomain `static.`
    	assets := app.Subdomain("static")
    	assets.HandleDir("/", iris.Dir("./public"), iris.DirOptions{
    		Compress:  true,
    		DirList:   iris.DirList,
    		IndexName: "/index.html",
    		ShowList:  false,
    		Cache: iris.DirCacheOptions{
    			Enable:          true,
    			CompressIgnore:  iris.MatchImagesAssets,
    			CompressMinSize: 1,
    			Encodings:       []string{"gzip", "br", "deflate", "snappy"},
    		},
    	})
    
    	// redirect root domain to `your.`
    	app.SubdomainRedirect(app, your)
    
    	// Redirect www subdomains to `your.`
    	app.SubdomainRedirect(app.Subdomain("www"), your)
    
  • AutoTLS with non-80 HTTP Port?

    AutoTLS with non-80 HTTP Port?

    Hello there!

    This is a purely documentation / example question:

    • How can I start an AutoTLS server, where the HTTP port is 8080 and not 80?

    Why?

    Because there is NAT in front of iris that routes internal:8080 to external:80

    Current Code

    if err := app.Run(iris.AutoTLS(":443", "my.domain.here", "[email protected]")); err != nil {
      log.Error("failed to set-up HTTP server", "error", err)
    }
    

    Looking through the code some I the two ways to create a Runner that conflict here: https://github.com/kataras/iris/blob/da029d6f37228c7c0fed685187a2bd4ef35b5b3e/iris.go#L658-L667 https://github.com/kataras/iris/blob/da029d6f37228c7c0fed685187a2bd4ef35b5b3e/iris.go#L584-L590

    They are simply too abstracted for me to know what I'd be changing without a thorough deep-dive into iris code.

  • [FEATURE REQUEST] MVC serving gRPC-compatible controller

    [FEATURE REQUEST] MVC serving gRPC-compatible controller

    Is your feature request related to a problem? Please describe.

    currently iris mvc would accept a controller func like

    
    func (s *acctService) PostLogin(ctx iris.Context, input *LoginParam) (*LoginResult, error) {}
    
    

    It just like a grpc service func, but when i change iris.Context to context.Context, it cause panic. Instead writing a wrapper func, could iris.MVC support context.Context as input parameter? If ture, then all the grpc services could serve by iris.MVC without adding a line.

    Describe the solution you'd like could accept like this

    
    func (s *acctService) PostLogin(ctx context.Context, input *LoginParam) (*LoginResult, error) {}
    
    

    Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.

    Additional context Add any other context or screenshots about the feature request here.

  • Poor performance of session.UpdateExpiration on 200 thousands+ keys with new radix lib

    Poor performance of session.UpdateExpiration on 200 thousands+ keys with new radix lib

    Hello Makis!

    I have more 200 thousands key in redis on prod server and found that after upgrading iris on v11 from redigo to radix lib that I have problems with perfomance when calling session.UpdateExpiration method (it`s executing minimum 10 seconds on a powerful prod server and more than 30 seconds on usual local).

    While debugging I found place where freezes, it`s here:

    func (r *Service) UpdateTTLMany(prefix string, newSecondsLifeTime int64) error {
    	keys, err := r.getKeys(prefix)
    	if err != nil {
    		return err
    	}
    ...
    }
    

    and inside getKeys here:

    scanner := radix.NewScanner(r.pool, radix.ScanOpts{
    		Command: "SCAN",
    		Pattern: r.Config.Prefix + prefix + r.Config.Delim + "*", // get all of this session except its root sid.
    		//	Count: 9999999999,
    	})
    
    	var key string
    	for scanner.Next(&key) {
    		keys = append(keys, key)
    	}
    

    Just has watched old v10 iris and old method getKeysConn did not cause such delay ...

    func (r *Service) getKeysConn(c redis.Conn, prefix string) ([]string, error) {
    	if err := c.Send("SCAN", 0, "MATCH", r.Config.Prefix+prefix+"*", "COUNT", 9999999999); err != nil {
    		return nil, err
    	}
    
    	if err := c.Flush(); err != nil {
    		return nil, err
    	}
    
    	reply, err := c.Receive()
    	if err != nil || reply == nil {
    		return nil, err
    	}
    

    Maybe reason in difference between old and new scan commands? Could you help?

  • [BUG/Feature] MVC Dependency authentication example

    [BUG/Feature] MVC Dependency authentication example

    Describe the bug on the master branch "https://github.com/kataras/iris/blob/master/_examples/mvc/authenticated-controller/main.go" an authentication is used to show how it is done when you search for an authenticated user. But how can I find an unauthenticated user who can call the same route but from a different controller?

    To Reproduce Steps to reproduce the behavior:

    1. [...]

    Expected behavior Let's take two controllers that are both registered for the same route, but one of them has no authentication feature. Now when I call the route, I want the call without authentication to return a different value than if I were authenticated.

    Screenshots If applicable, add screenshots to help explain your problem.

    Desktop (please complete the following information):

    • OS: [e.g. ubuntu, windows]

    Additional context I don't think it's a bug, but a feature request, although I think others do as well, that the same route should call a different controller under different circumstances.

  • [FEATURE REQUEST] Make i18n expandable

    [FEATURE REQUEST] Make i18n expandable

    I come from the corner of GNU Gettext users. I would like to have something similar for the i18n implementation.

    What requirements would I have:

    • Loader (local and binary)
    • Gettext functions, so that several domains and contexts can be used.
    • message interfaces
    • PO/MO support, JSON (i18n-next etc.), the current ini format

    https://github.com/leonelquinteros/gotext (with serveral fixes: https://git.deineagentur.com/DeineAgenturUG/gotext) could serve as a basis for inspiration.

    What do you think?

  • [BUG] when dynamic routing parameters have type judgments, cause cors problem

    [BUG] when dynamic routing parameters have type judgments, cause cors problem

    Thanks for your contribution!

    Describe the bug when dynamic routing parameters have type judgments, cause cors problem

    To Reproduce Steps to reproduce the behavior:

    func main() {
    	app := iris.New()
    	app.Use(cors.AllowAll())
    	app.AllowMethods(iris.MethodOptions)
    	app.Delete("user/{id}", user.deleteUser) // no cors problem
    	app.Delete("user/{id:uint64}", user.deleteUser) // has cors problem
    	_ = app.Run(iris.Addr(":8080"))
    }
    

    Expected behavior Fix it

    Desktop (please complete the following information):

    • OS: MacOS
  • Cookies not set

    Cookies not set

           outh := app.Party("/v1", func(ctx iris.Context) {
    		tmpl := iris.HTML("./templates", ".html")
    		tmpl.Reload(true)
    		app.RegisterView(tmpl)
    		ctx.View("/outh/outh.html")
    	})
    
    	outh.Get("/test", func(ctx iris.Context) {
    		ctx.SetCookieKV("test", "testvalue")
    	})
    

    Why doesn't it set cookies?

    If you do this: https://github.com/iris-contrib/examples/blob/master/cookies/basic/main.go, then cookies are set

    how to make it work in my example?

  • [BUG]dynamic routing does not take effect

    [BUG]dynamic routing does not take effect

    Describe the bug regularly extract integers in URLs

    To Reproduce Steps to reproduce the behavior:

    func App() *iris.Application {
    	app := iris.New()
    	template := iris.Django("./template", ".html")
    	// 始终动态加载
    	template.Reload(true)
    	app.RegisterView(template)
            app.Get("/category/aaa/{uid:uint}", adminController.CategoryAdd)
            app.Get("/category/bbb/{uid:string regexp([0-9]{1,20})}.html", adminController.CategoryAdd)
            app.Get("/category/ccc/{uid:uint}.html", adminController.CategoryAdd)
            app.Get("/category/ddd/{uid:uint regexp(\\d+)}.html", adminController.CategoryAdd)
    
            uidExpr := "^[0-9]{1,20}?$"
    	        uidRegex, err := regexp.Compile(uidExpr)
    	        if err != nil {
    		        panic(err)
    	        }
    	app.Macros().Get("string").RegisterFunc("getUid", uidRegex.MatchString)
    	app.Get("/category/eee/{uid:string getUid() else 502}.html", adminController.CategoryAdd)
    }
    

    view

    func CategoryAdd(ctx iris.Context) {
    	uid := ctx.Params().GetUintDefault("uid", 0)
    	fmt.Printf("uid:%v\n", uid)
            ctx.View("admin/category_add.html")
    }
    

    Expected behavior url :

    /category/aaa/1111    uid=111   working
    /category/bbb/222    uid=0     working
    /category/ccc/3333.html        404   return not found
    /category/ddd/444.html          404   return not found
    /category/eee/444.html          404   return not found
    

    i want to

    /category/aaa/1111    uid=111   working
    /category/bbb/222    uid=222     working
    /category/ccc/3333.html          uid=3333 working
    /category/ddd/444.html           uid=444   working
    /category/eee/555.html            uid=555   working
    

    how to solve?

    Desktop (please complete the following information): mac

    iris.Version v12

    Please make sure the bug is reproducible over the master branch:

  • How does django AddFunc call context content

    How does django AddFunc call context content

    How does django AddFunc call context content

    tmpl.AddFunc("activeClass", func(routeName string) string {
                //get context url??
    	return routeName
    })
    
  • how to convert string to html language

    how to convert string to html language

    my string:

    ayer.open({
                        type: 1
                        ,title: false 
                        ,closeBtn: false
                        ,area: '300px;'
                        ,shade: 0.8
                        ,id: 'LAY_layuipro' 
                        ,btn: ["admin","index"]
                        ,btnAlign: 'c'
                        ,moveType: 1 
                        ,content: '<div style="padding: 50px; line-height: 22px;font-weight: 300;"> layer.msg(install sucess)</div>'
                        ,success: function(layero){
                            var btn = layero.find('.layui-layer-btn');
                            "btn.find('.layui-layer-btn0').attr({href: '/system/',target: '_blank'});btn.find('.layui-layer-btn1').attr({href: '/',target: '_blank'});"
    
                        }
                    });
    

    html

    <!DOCTYPE html>
    <html lang="zh-cn">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>安企CMS(AnqiCMS)初始化安装</title>
        <style>
            .container {
                padding: 30px;
            }
    
            .title {
                text-align: center;
                padding: 20px;
            }
    
            .layui-form {
                max-width: 600px;
                margin: 50px auto;
                padding: 20px;
                max-width: 600px;
                box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3);
                border-radius: 5px;
            }
    
            .layui-form-item {
                display: flex;
                margin-bottom: 20px;
                align-items: top;
            }
    
            .layui-form-label {
                padding: 6px 0;
                width: 100px;
            }
    
            .layui-input-block {
                flex: 1;
            }
    
            .layui-input {
                box-sizing: border-box;
                width: 100%;
                padding: 2px 10px;
                border: 1px solid #eaeaea;
                border-radius: 4px;
                height: 36px;
                font-size: 15px;
            }
    
            input:focus,
            textarea:focus {
                outline: 1px solid #29d;
            }
    
            .layui-form-mid {
                padding: 3px 0;
            }
    
            .layui-aux-word {
                color: #999;
                font-size: 12px;
            }
    
            .layui-btn {
                cursor: pointer;
                border-radius: 2px;
                color: #555;
                background-color: #fff;
                padding: 10px 15px;
                margin: 0 5px;
                border: 1px solid #eaeaea;
            }
    
            .layui-btn.btn-primary {
                color: #fff;
                background-color: #3f90f9;
            }
    
            .submit-buttons {
                text-align: center;
            }
        </style>
    </head>
    
    <body>
    <div class="container">
        <h1 class="title">初始化安装</h1>
        <form class="layui-form" action="/install" method="post">
            <div>
                <div class="layui-form-item">
                    <label class="layui-form-label">数据库地址</label>
                    <div class="layui-input-block">
                        <input type="text" name="host" value="localhost" required placeholder="一般是localhost"
                               autocomplete="off" class="layui-input">
                    </div>
                </div>
                <div class="layui-form-item">
                    <label class="layui-form-label">数据库端口</label>
                    <div class="layui-input-block">
                        <input type="text" name="port" value="3306" required placeholder="一般是3306" autocomplete="off"
                               class="layui-input">
                    </div>
                </div>
                <div class="layui-form-item">
                    <label class="layui-form-label">数据库名称</label>
                    <div class="layui-input-block">
                        <input type="text" name="database" value="anqicms" required placeholder="安装到哪个数据库"
                               autocomplete="off" class="layui-input">
                        <div class="layui-form-mid layui-aux-word">如果数据库不存在,程序则会尝试创建它</div>
                    </div>
                </div>
                <div class="layui-form-item">
                    <label class="layui-form-label">数据库用户</label>
                    <div class="layui-input-block">
                        <input type="text" name="user" required placeholder="填写数据库用户名" autocomplete="off"
                               class="layui-input">
                    </div>
                </div>
                <div class="layui-form-item">
                    <label class="layui-form-label">数据库密码</label>
                    <div class="layui-input-block">
                        <input type="password" name="password" required placeholder="填写数据库密码" autocomplete="off"
                               class="layui-input">
                    </div>
                </div>
            </div>
            <div class="layui-form-item">
                <label class="layui-form-label">后台用户名</label>
                <div class="layui-input-block">
                    <input type="text" name="admin_user" value="admin" required placeholder="用于登录管理后台"
                           autocomplete="off" class="layui-input">
                </div>
            </div>
            <div class="layui-form-item">
                <label class="layui-form-label">后台密码</label>
                <div class="layui-input-block">
                    <input type="password" name="admin_password" minlength="6" maxlength="20" required
                           placeholder="请填写6位以上的密码" autocomplete="off" class="layui-input">
                </div>
            </div>
            <div class="layui-form-item">
                <label class="layui-form-label">网站地址</label>
                <div class="layui-input-block">
                    <input type="text" name="base_url" value="" autocomplete="off" class="layui-input">
                    <div class="layui-form-mid layui-aux-word">
                        指该网站的网址,如:https://www.anqicms.com,用来生成全站的绝对地址
                    </div>
                </div>
            </div>
            <div class="layui-form-item">
                <div class="layui-input-block submit-buttons">
                    <button type="reset" class="layui-btn">重置</button>
                    <button class="layui-btn btn-primary" type="submit">确认初始化</button>
                </div>
            </div>
        </form>
    </div>
    </body>
    <script src="https://www.layuicdn.com/layui/layui.js"></script>
    <script>
        {{ if .message }}
            {{ $length := len .btns }}{{ if eq $length 0 }}
                layer.msg({{.message}})
            {{else}}
                layer.open({
                        type: 1
                        ,title: false //不显示标题栏
                        ,closeBtn: false
                        ,area: '300px;'
                        ,shade: 0.8
                        ,id: 'LAY_layuipro' //设定一个id,防止重复弹出
                        ,btn: {{.btns}}
                        ,btnAlign: 'c'
                        ,moveType: 1 //拖拽模式,0或者1
                        ,content: '<div style="padding: 50px; line-height: 22px;font-weight: 300;"> layer.msg({{.message}})</div>'
                        ,success: function(layero){
                            var btn = layero.find('.layui-layer-btn');
                            {{.links}}
    
                        }
                    });
            {{end}}
        {{ end }}
    
    
    </script>
    </html>
    

    context

    type Button struct {
    	Name string
    	Link string
    }
    
    func Install(ctx iris.Context) {
    	fmt.Println("........")
    	if dao.DB != nil {
    		ctx.Redirect("/")
    		return
    	}
    
    	templateName := "install.html"
    	//data := iris.Map{
    	//	"message": "",
    	//	"bts":     []Button{},
    	//}
    	button := []Button{
    		{Name: "admin", Link: "/system/"},
    		{Name: "index", Link: "/"},
    	}
    
    	links := ""
    	btns := []string{}
    	i := 0
    	for _, btn := range button {
    		links += fmt.Sprintf("btn.find('.layui-layer-btn%v').attr({href: '%v',target: '_blank'});", i, btn.Link)
    		btns = append(btns, btn.Name)
    		i += 1
    	}
    	data := iris.Map{
    		"message": "install success",
    		"btns":    btns,
    		"links":   links,
    	}
    	ctx.View(templateName, data)
    	return
    }
    
  • Grpc not working as expected

    Grpc not working as expected

    Describe the issue you are facing or ask for help

    @kataras, it is not a issue, rather a question. It is been three days, I am trying the mvc.Grpc. I didn't try the example provided in the repo.

    But, I keep getting this error.

    "err rpc error: code = Unimplemented desc = unexpected HTTP status code received from server: 404 (Not Found); transport: received unexpected content-type "text/plain; charset=utf-8"
    

    If I serve my grpc service using standard grpc provided documentation, it is working.

    lis, _ := net.Listen("tcp", fmt.Sprintf("localhost:%d", 50051))
    serv.Serve(lis)
    

    And if I serve the server using Iris like below, it works only on postman or over http.Post

    app.Run(
        iris.TLS("localhost:50051", "config/server.crt", "config/server.key")
    )
    

    I tried different hostname, such as "127.0.0.1" or "0.0.0.0" also tried without hostname, only the port. Nothing works.

    On my client side, I also tried different credentials. No luck at all.

    // cred, err := credentials.NewClientTLSFromFile("./server.crt", "")
    // or
    // cred := insecure.NewCredentials()
    // or
    cred := credentials.NewTLS(&tls.Config{
    	InsecureSkipVerify: true,
    	Renegotiation:      tls.RenegotiateNever,
    })
    
    conn, err := grpc.Dial(
    	address,
    	grpc.WithTransportCredentials(cred),
    )
    

    Server example, I did also tried with different strict mode.

    app := iris.New()
    app.Logger().SetLevel("debug")
    handler := internal.CreateGrpcHandler()
    
    serv := grpc.NewServer()
    pb.RegisterApiServer(serv, handler)
    
    mvc.New(app).
    Handle(handler, mvc.GRPC{
    	Server:      serv,          // Required.
    	ServiceName: "product.Api", // Required.
    	Strict:      false,
    })
    app.Run(
           addr = iris.TLS(config.GRPC_ADDR, "config/server.crt", "config/server.key"),
    )
    

    The logs shows it is running, and as I said, the https over postman working.

    [DBUG] internal.grpcHandler
      ╺ Create
          POST /product.Api/Create
        • context.Context           
        • *product.CreateProductReq → ...:32
      ╺ Delete
          POST /product.Api/Delete
        • context.Context           
        • *product.DeleteProductReq → ...:32
      ╺ Read
          POST /product.Api/Read
        • context.Context           
        • *product.ReadProductReq   → ...o:32
      ╺ Update
          POST /product.Api/Update
        • context.Context           
        • *product.UpdateProductReq → ...:32
    [DBUG] 2022/10/14 23:24 API: 5 registered routes (1 GET and 4 POST)
    GET: / (./cmd/grpc.go:24)
    
    POST: /product.Api/Create gRPC internal.grpcHandler (./cmd/grpc.go:32)
          • internal.grpcHandler.Create (./internal/grpc.go:16)
    POST: /product.Api/Delete gRPC internal.grpcHandler (./cmd/grpc.go:32)
          • internal.grpcHandler.Delete (./internal/grpc.go:47)
    POST: /product.Api/Read gRPC internal.grpcHandler (./cmd/grpc.go:32)
          • internal.grpcHandler.Read (./internal/grpc.go:33)
    POST: /product.Api/Update gRPC internal.grpcHandler (./cmd/grpc.go:32)
          • internal.grpcHandler.Update (./internal/grpc.go:40)
    
    Iris Version: 12.2.0-beta5
    
    Now listening on: https://localhost:50051
    Application started. Press CTRL+C to shut down.
    

    I am quite confused now, either the beta version is broken or I missed something in my code.

Gouweb: A web framework for go inspired by laravel

gouweb is a web framework for go inspired by laravel Installation go get -u gith

Feb 17, 2022
Go-igni: monolith-based web-framework in Go Inspired by classical PHP Frameworks like CodeIgnier & Laravel

go-igni Web Framework in Go About This is research project about developing monolith-based web-framework in Go Inspired by classical PHP Frameworks li

Feb 25, 2022
laravel for golang,goal,fullstack framework,api framework
laravel for golang,goal,fullstack framework,api framework

laravel for golang,goal,fullstack framework,api framework

Feb 24, 2022
hiboot is a high performance web and cli application framework with dependency injection support

Hiboot - web/cli application framework About Hiboot is a cloud native web and cli application framework written in Go. Hiboot is not trying to reinven

Nov 20, 2022
re:Web enables classic web applications to run on AWS Lambda.
re:Web enables classic web applications to run on AWS Lambda.

re:Web re:Web enables classic web applications to run on AWS Lambda. re:Web interfaces with the Lambda Runtime API. It translates API Gateway requests

Jan 1, 2023
A lightweight MVC framework for Go(Golang)

utron utron is a lightweight MVC framework in Go (Golang) for building fast, scalable and robust database-driven web applications. Features Postgres,

Nov 26, 2022
⚡ Rux is an simple and fast web framework. support middleware, compatible http.Handler interface. 简单且快速的 Go web 框架,支持中间件,兼容 http.Handler 接口

Rux Simple and fast web framework for build golang HTTP applications. NOTICE: v1.3.x is not fully compatible with v1.2.x version Fast route match, sup

Dec 8, 2022
基于Golang的框架Gin开发,项目结构和理念参考Laravel。现支持:MySQL、Redis、MVC、拦截器、助手函数、fresh热更、swagger-UI、tpl模版输出、安全的Api。

GinLaravel的构建和运行周期与Beego、Vue、React、Laravel、ThinkPHP、Django等都会有类似的引导思路、参数设置、插件扩展、服务部署、代码统一性、生态护城河等。

Nov 18, 2022
Mvc+go+mysqlのrest API テンプレートリポジトリ

rest-api-temp リポジトリ概要 アドベントカレンダー用に作成 https://qiita.com/advent-calendar/2021/hcb-2021 用途 迅速にrest apiを作らなきゃいけない場合のテンプレート 注意 テンプレートAPIの使用はdocs/api.mdに記載

Dec 15, 2021
Headless CMS with automatic JSON API. Featuring auto-HTTPS from Let's Encrypt, HTTP/2 Server Push, and flexible server framework written in Go.
Headless CMS with automatic JSON API. Featuring auto-HTTPS from Let's Encrypt, HTTP/2 Server Push, and flexible server framework written in Go.

Ponzu Watch the video introduction Ponzu is a powerful and efficient open-source HTTP server framework and CMS. It provides automatic, free, and secur

Dec 28, 2022
Flamingo Framework and Core Library. Flamingo is a go based framework for pluggable web projects. It is used to build scalable and maintainable (web)applications.
Flamingo Framework and Core Library. Flamingo is a go based framework for pluggable web projects. It is used to build scalable and maintainable (web)applications.

Flamingo Framework Flamingo is a web framework based on Go. It is designed to build pluggable and maintainable web projects. It is production ready, f

Jan 5, 2023
Golanger Web Framework is a lightweight framework for writing web applications in Go.

/* Copyright 2013 Golanger.com. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

Nov 14, 2022
The jin is a simplified version of the gin web framework that can help you quickly understand the core principles of a web framework.

jin About The jin is a simplified version of the gin web framework that can help you quickly understand the core principles of a web framework. If thi

Jul 14, 2022
A minimal framework to build web apps; with handler chaining, middleware support; and most of all standard library compliant HTTP handlers(i.e. http.HandlerFunc).
A minimal framework to build web apps; with handler chaining, middleware support; and most of all standard library compliant HTTP handlers(i.e. http.HandlerFunc).

WebGo v4.1.3 WebGo is a minimalistic framework for Go to build web applications (server side) with zero 3rd party dependencies. Unlike full-fledged fr

Jan 1, 2023
lightweight, idiomatic and composable router for building Go HTTP services

chi is a lightweight, idiomatic and composable router for building Go HTTP services. It's especially good at helping you write large REST API services

Jan 6, 2023
:exclamation::exclamation::exclamation: [deprecated] Moved to https://github.com/go-macaron/macaron
:exclamation::exclamation::exclamation: [deprecated] Moved to https://github.com/go-macaron/macaron

Macaron Package macaron is a high productive and modular web framework in Go. Current version: 0.6.8 Getting Started The minimum requirement of Go is

Aug 20, 2021
gin auto binding,grpc, and annotated route,gin 注解路由, grpc,自动参数绑定工具
gin auto binding,grpc, and annotated route,gin 注解路由, grpc,自动参数绑定工具

中文文档 Automatic parameter binding base on go-gin doc Golang gin automatic parameter binding Support for RPC automatic mapping Support object registrati

Jan 3, 2023
Roche is a Code Generator and Web Framework, makes web development super concise with Go, CleanArch
Roche is a Code Generator and Web Framework, makes web development super concise with Go, CleanArch

It is still under development, so please do not use it. We plan to release v.1.0.0 in the summer. roche is a web framework optimized for microservice

Sep 19, 2022