Search code examples
haskellservant

How to implement conditional endpoints with Servant?


I have an existing server written using the Servant library. I now want to make the endpoints conditional such that based on certain configuration or logic, I would like to serve (or not serve) a particular endpoint. What's the best way to do this?

I've tried using EmptyAPI from Servant.API but it didn't work. For context, I'm currently using toServant from Servant.API.Generic for most of my routes.


Solution

  • If you're ok with returning 404 when the endpoint is "off", you can do that by throwing the corresponding Servant error:

    server = toServant MyEndpointsRecord
        { ...
    
        , cleverEndpoint = do
            shouldServe <- isCleverEndpointEnabled
            if shouldServe 
                then serveCleverEndpoint
                else throwError err404
    
        ...
        }
    

    You can also wrap this for reuse if you need to do this often:

    guarded checkConfig f = do
        shouldServe <- checkConfig
        if shouldServe 
            then f
            else throwError err404
    
    
    server = toServant MyEndpointsRecord
        { ...
    
        , cleverEndpoint = guarded isCleverEndpointEnabled serveCleverEndpoint
    
        ...
        }