如何将多个请求DTO映射到单个路由

Jes*_*ebb 3 c# rest url-routing dto servicestack

我一直在试验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
}
Run Code Online (Sandbox Code Playgroud)

我想创建一个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; }
}
Run Code Online (Sandbox Code Playgroud)

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

public class StudentList : List<Student>
{
}

public class Student
{
    public int Id { get; set; }
    public String Email { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

注意:此Reponse DTO Student类与我的DomainModel类是分开的; 它们位于不同的名称空间中.

不幸的是,当我尝试使用这些路线时,每个请求/students?<anything>最终都会返回所有学生.唯一可行的路线是如果我发出GET请求/students/123,然后我带着Id 123返回学生.我认为这不起作用,因为我正在"/students"为多个请求DTO 重新使用路由定义.

我一直在阅读ServiceStack 维基示例,但我无法弄清楚如何完成我正在尝试的内容.我可以找到有关高级路由的最详细的文档是"新API"页面"智能路由"部分,但它也没有真正解决这种情况.

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

myt*_*thz 5

ByXXX您的Request DTO上添加后缀是ServiceStack中的代码嗅觉,他们希望鼓励设计基于消息的粗粒度接口.请参阅前面的答案,如何使用ServiceStack设计基于消息的API以及为什么要按响应类型调用语义服务进行分组

在这种情况下,你有一个服务做了Get一个独特的编号返回一个单一的学生,你也希望有一个Search电子邮件返回多个学生.所以在这种情况下我会有以下服务:

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

哪个会处理/students/123.

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

哪个可以用来处理:

  • /students
  • /students?id=123 //但返回List<Student>而不是
  • /students?email=foo@example.com
  • /students?id=123&email=foo@example.com
  • 等等

虽然我个人不会在Id这里添加,因为它是Get而不是Filter.