You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Servant中复用API类型并传递多段路径参数?

解决Servant框架中复用API类型传递多段路径的问题

问题根源

  1. 直接传递"hello/world"会被Servant当作单段路径,无法正确拆分;
  2. ("hello" :> "world")的kind是Type -> Type(需要后续拼接API终点),但原MyAPI定义要求第一个参数为Type,导致类型不匹配;
  3. 未开启必要扩展时,Haskell不允许将部分应用的类型构造器作为参数传递。

可行解决方案

方案1:调整API类型参数为类型构造器(推荐)

开启PolyKinds扩展,让API接受Type -> Type类型的构造器参数,直接拼接多段路径:

{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE PolyKinds #-}

import Servant.API

-- 复用的API类型,endpointTail为类型构造器(Type -> Type)
type MyAPI (endpointTail :: Type -> Type) result = 
  "blah" :> Capture "a" A :> endpointTail (Get '[JSON] result)

-- 定义多段路径的构造器
type HelloWorldTail t = "hello" :> "world" :> t

-- 使用示例:单段/多段路径均支持
type MyHelloAPI = MyAPI ("hello" :> ) HelloT  -- 单段路径,用部分应用的:>
type MyHelloWorldAPI = MyAPI HelloWorldTail HelloWorldT

方案2:用类型家族处理路径列表

通过类型家族将类型级字符串列表转换为:>连接的路径,更灵活支持任意段数的路径:

{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DataKinds #-}

import Servant.API
import GHC.TypeLits

-- 类型家族:将路径列表转换为Servant API片段
type family PathSegments (segments :: [Symbol]) (next :: Type) :: Type where
  PathSegments '[] next = next
  PathSegments (s ': ss) next = s :> PathSegments ss next

-- 复用的API类型,接受路径列表参数
type MyAPI (segments :: [Symbol]) result = 
  "blah" :> Capture "a" A :> PathSegments segments (Get '[JSON] result)

-- 使用示例
type MyHelloAPI = MyAPI '["hello"] HelloT  -- 单段路径
type MyHelloWorldAPI = MyAPI '["hello", "world"] HelloWorldT  -- 多段路径

方案3:基于Servant Generic的组件化复用

适合大型API场景,通过Generic定义可复用的API组件:

{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE PolyKinds #-}

import Servant.API
import Servant.API.Generic
import GHC.Generics

-- 定义可复用的基础API片段
data BlahAPI route = BlahAPI
  { _blahEndpoint :: route :- "blah" :> Capture "a" A :> route
  } deriving Generic

-- 组合多段路径与终点
type MyHelloWorldAPI = ToServantApi (BlahAPI (RecursiveRoute "hello" :> "world" :> Get '[JSON] HelloWorldT))

内容的提问来源于stack exchange,提问作者Clinton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 06:40:23