Reputation: 45243
I have been experimenting with the ServiceStack framework to develop a simple REST API. I am having troubles trying to define the Routes properly to handle the different URLs I desire.
I have a simple DomainModel class:
public class Student
{
public int Id { get; set; } // unique
public string Email { get; set; } // not unique
// some other properties and business logic
}
I would like to create a REST service which responds to HTTP requests to the following URLs:
/students
/students/123
/students?id=123
/[email protected]
I have tried using the following Request DTOs to accomplish this:
[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; }
}
As you can see, I am only trying to use two different Response DTOs:
public class StudentList : List<Student>
{
}
public class Student
{
public int Id { get; set; }
public String Email { get; set; }
}
Note: This Reponse DTO Student
class is separate than my DomainModel class; they are in different namespaces.
Unfortunately, when I try to use these routes, every request to /students?<anything>
ends up returning all students. The only Route that does work is if I make a GET request to /students/123
, then I get back Student with Id 123. I assume this isn't working because I am re-using the "/students"
Route definition for multiple Request DTOs.
I have been reading through the ServiceStack wiki and examples but I can not figure out how to accomplish what I am attempting. The most detailed documentation I can find about advanced routing is the "Smart Routing" section of the "New API" page but it doesn't really address this situation either.
How can I re-use the same Route definition for mulitple Request DTOs?
Upvotes: 3
Views: 1377
Reputation: 143319
Having ByXXX
suffixes on your Request DTOs is a code-smell in ServiceStack who wants to encourage the design of message-based coarse-grained interfaces. Please see this earlier answer on How to design a Message-Based API with ServiceStack and why you should group services by response types and call semantics
In this case you have a service doing a Get
on a Unique Id returning a single Student and you also wish to have a Search
on Email which returns multiple Students. So in this case I would have the following services:
[Route("/students/{Id}")]
public GetStudent : IReturn<Student>
{
public int Id { get; set; }
}
Which would handle just /students/123
.
[Route("/students")]
public FindStudents : IReturn<List<Student>>
{
public int? Id { get; set; }
public string Email { get; set; }
}
Which can be used to handle:
/students
/students?id=123
//but returns List<Student>
instead/[email protected]
/students?id=123&[email protected]
Although I personally wouldn't include an Id
here since it's a Get instead of a Filter.
Upvotes: 5