3

我一直在尝试使用ServiceStack框架来开发一个简单的 REST API。我在尝试正确定义路由以处理我想要的不同 URL 时遇到了麻烦。

我有一个简单的 DomainModel 类:

public class Student
{
    public int Id { get; set; } // unique
    public string Email { get; set; } // not unique

    // some other properties and business logic
}

我想创建一个 REST 服务来响应对以下 URL 的 HTTP 请求:

  • /students
    • GET 返回所有学生
  • /students/123
    • GET 返回 ID = 123 的学生
  • /students?id=123
    • GET 返回 ID = 123 的学生
  • /students?email=foo@example.com
    • GET 返回具有匹配电子邮件的所有学生

我尝试使用以下请求 DTO 来完成此操作:

[Route("/students", "GET")]
public class GetAllStudents : IReturn<StudentList>
{
}

[Route("/students", "GET")] // I want this to be for /students?Id=
[Route("/students/{Id}", "GET")]
public class GetStudentById : IReturn<Student>
{
    public int Id { get; set; }
}

[Route("/students", "GET")] // I want this to be for /students?Email=
public class GetStudentsByEmail : IReturn<StudentList>
{
    public string Email { get; set; }
}

如您所见,我只是尝试使用两种不同的响应 DTO:

public class StudentList : List<Student>
{
}

public class Student
{
    public int Id { get; set; }
    public String Email { get; set; }
}

注意:这个 Reponse DTOStudent类与我的 DomainModel 类是分开的;它们位于不同的名称空间中。

不幸的是,当我尝试使用这些路线时,每个请求/students?<anything>最终都会返回所有学生。唯一有效的 Route 是,如果我向 发出 GET 请求/students/123,那么我会返回 ID 为 123 的 Student。我认为这不起作用,因为我正在"/students"为多个 Request DTO 重新使用 Route 定义。

我一直在阅读 ServiceStack wiki示例,但我不知道如何完成我正在尝试的内容。我能找到的关于高级路由的最详细的文档是“新 API”页面的“智能路由”部分,但它也没有真正解决这种情况。

如何为多个请求 DTO 重复使用相同的路由定义?

4

1 回答 1

5

在您的请求 DTO 上添加后缀是ServiceStackByXXX中的一种代码味道,它希望鼓励设计基于消息的粗粒度接口。请参阅有关如何使用 ServiceStack 设计基于消息的 API以及为什么应按响应类型调用语义对服务进行分组的早期答案

在这种情况下,您有一个服务在返回单个学生Get唯一 ID上执行,并且您还希望有一个返回多个学生的电子邮件。因此,在这种情况下,我将拥有以下服务:Search

[Route("/students/{Id}")]
public GetStudent : IReturn<Student>
{
    public int Id { get; set; }
}

哪个会处理/students/123

[Route("/students")]
public FindStudents : IReturn<List<Student>>
{
    public int? Id { get; set; }
    public string Email { get; set; }
}

可用于处理:

  • /students
  • /students?id=123 //但List<Student>改为返回
  • /students?email=foo@example.com
  • /students?id=123&email=foo@example.com
  • ETC

尽管我个人不会在Id此处包含 an ,因为它是Get而不是Filter

于 2013-05-10T20:08:20.270 回答