Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serve SPA files and /api route #9

Closed
mikepc opened this issue Aug 12, 2016 · 5 comments
Closed

Serve SPA files and /api route #9

mikepc opened this issue Aug 12, 2016 · 5 comments

Comments

@mikepc
Copy link

mikepc commented Aug 12, 2016

Hello there - I'm trying to configure iris to do a couple of things.

I want it to serve up static content for an angular SPA (in html5 mode) which means I will want to redirect all routes that don't start with /api to the static middleware, but for all actions below /api I will have custom handlers.

Code:
package main

import (
"github.com/kataras/iris"
// "github.com/kataras/iris/utils"
// "strings"
)

func allVendorBrandLabel(c *iris.Context) {
c.WriteString("Hello, api :)")

}
func main() {

    iris.Get("/api/all", allVendorBrandLabel)
    iris.StaticWeb("/", "./www", 2)
    iris.Listen(":8080")

}

This results in the root route failing with a 404, but the /api/ call returns nominally.

What do I need to accomplish this?

I also posted the question to StackOverflow to see how I could get it working:
http://stackoverflow.com/questions/38922585/how-to-serve-api-and-html5-spa-with-iris

@ghost
Copy link

ghost commented Aug 12, 2016

First of all, Static routes goes first, if you put it first it, correctly, gives you a panic: Error: Router: Path's part: '/api/all' conflicts with wildcard '/*filepath' in the route path: '/api/all' !

Yes, because iris.StaticWeb will override the /api/all it will think it as /api/all/index.html because you're using the StaticWeb. You could use the context.ServeFile on a wildcard /*path route, and inside this handler do a if path:= context.Param("path") ; path == "/api/all" { allVendorBrandLabel(context)} else { ctx.ServeFile(path) } try this and tell me the results. Or we could discuss ways to make a ready-to-use function for SPA with paths (html5)

@mikepc
Copy link
Author

mikepc commented Aug 12, 2016

Thank you very much for your very helpful response.

`func main() {

iris.Get("/*path", func(c *iris.Context) {
    path := c.Param("path")
    if path == "/api/all" {
        allVendorBrandLabel(c)
    } else {
        c.ServeFile("./www/index.html", true)
    }
})

iris.Listen(":8080")

}
`

That's the final code to get it to work.

It would be nice to have a more elegant way to approach this though, as the api portion of the app matures, it would be nice to handle it in a more similar way to other routes.

@ghost
Copy link

ghost commented Aug 12, 2016

I just think it simpler,

package main

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

// hosts: add these lines: (use tabs to separate them, if that doesn't works for you)
// 127.0.0.1 mydomain.com
// 127.0.0.1 api.mydomain.com
func main() {

	// OPTIONAL if you want diffent domain for static files
	// (I do this way but you are not forced to do the same)
	//
	// create the subdomain s.mydomain.com to serve our resources files
	// http://s.mydomain.com/resources/css/bootstrap.min.css ...
	// iris.Party("s.").StaticWeb("/", "./www/resources")
	//

	//
	// REGISTER YOUR REST API
	//

	// http://api.mydomain.com/ ...
	// brackers are optional, it's just a visual declaration.
	api := iris.Party("api.")
	{
		// http://api.mydomain.com/users/42
		api.Get("/users/:userid", func(ctx *iris.Context) {
			ctx.Writef("user with id: %s", ctx.Param("userid"))
		})

	}

	//
	// REGISTER THE PAGE AND ALL OTHER STATIC FILES
	// INCLUDING A FAVICON, CSS, JS and so on
	//

	// http://mydomain.com , here should be your index.html
	// which is the SPA frontend page
	iris.StaticWeb("/", "./www")

	//
	// START THE SERVER
	//
	iris.Listen("mydomain.com:80")
}
  • Or you could just use other iris station and server for static files and other for SPA,
statics := iris.New()
statics.StaticWeb("/","./www")
go statics.Listen(":9090")

iris.Get("/api/all",...)
iris.Listen(":8080")

@mikepc
Copy link
Author

mikepc commented Aug 12, 2016

You rock man, iris is the best Go web framework out there in my opinion, which is why when I came to this team at Nordstrom I used it for my first project. I have used it in the past for several microservices on other projects and it worked splendidly. Will keep checking back! Right now there's just one endpoint so I can get started.

@ghost
Copy link

ghost commented Jan 12, 2017

package main

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

func main() {
	usersAPI := iris.None("/api/users/:userid", func(ctx *iris.Context) {
		ctx.Writef("user with id: %s", ctx.Param("userid"))
	})("api.users.id")

      // third parameter is optional, if not empty then these routes 
      // will have priority over the static handler when the request path is one of their route's path
      iris.StaticWeb("/", "./www", usersAPI)

      iris.Listen("localhost:8080")
}

@mikepc Surprise :D

Discussion: https://github.com/kataras/iris/issues/585

@ghost ghost closed this as completed Jan 14, 2017
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant