Daniel Gartmann
Daniel Gartmann

Reputation: 13038

How to set the HTTP status code to 201 using ServiceStack without mixing business logic with transport logic?

When I perform a POST request in order to create an object on the server I expect a 201 HTTP status code set to the response header with the URI.

The problem is that I don't like to "decorate" my HTTP response headers within my service since I am mixing business logic with transport logic.

What's the recommended approach?

Upvotes: 0

Views: 422

Answers (1)

Scott
Scott

Reputation: 21511

You could use an attribute on your create actions. This makes it clear the status the method will return while not being directly involved in the action logic itself.

[AddHeader(HttpStatusCode.Created)]
public int Post(TestRequest request)
{
    return 0; // Record Id
}

A more elaborate way, if you really wanted to avoid marking up anything in your Service would be to decorate your response object DTO instead, with an interface that can be detected by a response filter, that will add the necessary headers.

So if we use an interface called ICreated

public interface ICreated
{
}

We can add it to our response DTO:

public class UserCreatedResponse : ICreated
{
    public int Id { get; set; }
}

Then when we return that type of response from our action method:

public class TestService : Service
{
    public UserCreatedResponse Post(CreateUserRequest request)
    {
        return new UserCreatedResponse { Id = 123 };
    }
}

It will receive the correct headers if we apply the following filter in the AppHost Configure method:

public override void Configure(Funq.Container container)
{
    GlobalResponseFilters.Add((req, res, obj) => {
        var result = obj as ICreated;
        if(result != null) {
            res.StatusCode = (int)HttpStatusCode.Created;
            res.StatusDescription = "Created";
        }
    });
}

Assumes a request DTO such as:

[Route("/User","POST")]
public class CreateUserRequest : IReturn<UserCreatedResponse>
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Upvotes: 3

Related Questions