1

I've added a few Actions on top of the CRUD ones, and I want to have custom routes to the new actions. But still, keep the CRUD actions with the same route (e.g. /ShowPost?postId=[uuid]

instance HasPath PostsController where
    -- ...
    pathTo ShowPostAction { postId } = "/ShowPost?postId=" ++ tshow postId


instance CanRoute PostsController where
   parseRoute' = do
       let posts = do
           string "/Posts"
           optional "/"
           endOfInput
           pure PostsAction

       let showPost = do
           string "/ShowPost?postId="
           postId <- parseId
           optional "/"
           endOfInput
           pure ShowPostAction { postId }


       posts <|> showPosts -- ...

I assume the CanRoute part isn't parsing correctly, as I end up with a 404 page when navigating to /ShowPost?postId=...

amitaibu
  • 1,026
  • 1
  • 7
  • 23

1 Answers1

2

The problem here is that the ?postId= is not part of the request path directly as it's part of the query string of the request.

Given a request like /ShowPost?postId=abc, then the parser input is actually just /ShowPost. The ?postId=abc is available through the ?context variable only.

You could try something like this (not tested):

instance HasPath PostsController where
    -- ...
    pathTo ShowPostAction { postId } = "/ShowPost?postId=" ++ tshow postId

-- Define the auto route instance
instance AutoRoute PostsController

instance CanRoute PostsController where
   parseRoute' = do
       let customRoutes = ...
       customRoutes <|> (autoRoute @PostsController)

Basically this would use your customRoutes parser first and then try to fallback to the parser by AutoRoute.

Marc Scholten
  • 1,351
  • 3
  • 5
  • 1
    Nice, thanks! Could something similar be achieved for the `HasPath` part? – amitaibu Jan 26 '22 at 19:45
  • Not possible right now. [We'd need to extract the `pathTo` implementation into a `autoRoutePathTo`](https://github.com/digitallyinduced/ihp/blob/master/IHP/RouterSupport.hs#L453) and then set `pathTo = autoRoutePathTo` for that type instance. – Marc Scholten Jan 28 '22 at 06:25
  • @marcsholten I think that would be valuable because I went to do this with a controller with a lot of actions where I only really needed to make a custom route for one or two of the actions and it became clear that it was going to be too much manual work to do that, and the better thing is probably that I break up my controller into more controllers. – Chris Schankula Jan 28 '22 at 15:39