The base of all routing in Neoroute is the Router object. It’s gonna be routing requests to all of your different routes. You can create one like this:
router := neoroute.NewRouter[neoroute.NoData](neoroute.Config{
// This function is pretty important, it converts any error you return from a handler
// function to an error message that will be sent to the client.
ErrorHandler: func(err error, c *Ctx[D]) string {}
})
Now, the place where neoroute.NoData currently is, is a generic value for any data associated with the connection. This data object is the one created in the HandshakeFunc of your transporter (most likely HTTP or WebSocket). You could use it to store account information, or anything else related to the connection.
In Neoroute, there generally are six different route types with the following properties:
| Routing function | Has request data | Has response data | Can error | Example use case |
|---|---|---|---|---|
| Route | ✅ | ✅ | ✅ | Regular request response |
| RouteNoRequest | ❌ | ✅ | ✅ | Getting something |
| RouteOk | ✅ | ❌ | ✅ | Selecting a character |
| RouteOkNoRequest | ❌ | ❌ | ✅ | Toggling a switch |
| RouteNoResponse | ✅ | ❌ | ❌ | Voice packets |
| RoutePing | ❌ | ❌ | ❌ | Heartbeat signals |
Their properties explained:
If there is no response data and no error returned, it means that the client will not expect any confirmation for the request they sent. All of the different routes are handy in different use cases. Choose which route you want to use based on your minimum requirements.
For naming your routes, we only the following characters: -, /, _, ~, ., all lowercase letters (a-z) and all numbers (0-9). Any uppercase letters will be made lowercase and any other characters will be truncated, so please just don’t use them.
To separate routes and their sub-routes we use /. Therefore, multiple / will also be reduced to just one. If the last character is a /, it will also be removed.
Here are examples for all of the different route definition functions we have:
// Comment below generates the required code for the structs.
//go:generate msgp
type SomeRequest struct { /* some fields */ }
type SomeResponse struct { /* some fields */ }
router.Route("some-route", func(c *neoroute.ResCtx[neoroute.NoData, SomeResponse], req SomeRequest) error {
return c.Respond(ResponseData{ /* fill out your struct */ })
})// Comment below generates the required code for the structs.
//go:generate msgp
type SomeResponse struct { /* some fields */ }
router.Route("some-route", func(c *neoroute.ResCtx[neoroute.NoData, SomeResponse]) error {
return c.Respond(ResponseData{ /* fill out your struct */ })
})// Comment below generates the required code for the structs.
//go:generate msgp
type SomeRequest struct { /* some fields */ }
router.RouteOk("some-route", func(c *neoroute.OkCtx[neoroute.NoData], req SomeRequest) error {
return c.RespondOk()
})router.RouteOkNoRequest("some-route", func(c *neoroute.OkCtx[neoroute.NoData]) error {
return c.RespondOk()
})// Comment below generates the required code for the structs.
//go:generate msgp
type SomeRequest struct { /* some fields */ }
router.RouteNoResponse("some-route", func(c *neoroute.Ctx[neoroute.NoData], req SomeRequest) error {
return c.RespondOk()
})router.RoutePing("some-route", func(c *neoroute.Ctx[neoroute.NoData]) {
// Do something
})When you’re in a route, you get access to the Session[neoroute.NoData] object you might already know from the transporter guides. You can get this object in routes as well, by calling ctx.Session().
Here are some useful things to know:
ctx.Session().UpdateData() lets you modify the session data in case you want to, this is fully concurrency safe.ctx.Session().Id() is a unique id assigned to the session. It is guaranteed to be unique for the connection backing this session.ctx.Session().Adapt() gives you a new adapter.Returned errors will be handled in the ErrorHandler of the router. Returning nil will cause a panic. You can also return an error message to the client directly like this:
return neoroute.NewError("your error message")
Any neoroute.NewError returns will not be forwarded to the ErrorHandler in the router as the message passed in already is the error message returned to the client.
This is just a short excerpt, here you can learn more about error handling.