我有几个与使用ServiceStack实现REST服务相关的问题。
对于GET操作,我将请求DTO定义如下:
[Route("/Customer/{ID}", Verbs = "GET")]
public class GetCustomer : IReturn<GetCustomerResponse>
{
....
....
}
此处“GetCustomer”是请求DTO,“GetCustomerResponse”是响应DTO。但是对于PUT / POST / DELETE操作,我只需要知道操作是否成功提交,如果'不'那么什么是异常。那么对于POST / PUT / DELETE我的请求dto定义应该是什么?它应该使用如下所示的IReturnVoid吗?
[Route("/Customer/{ID}", Verbs = "DELETE")]
public class DeleteCustomer : IReturnVoid
{
....
....
}
如果我必须使用IReturnVoid,那么如何检索提交操作时可能出现的任何异常信息?
在服务堆栈的错误处理文档中,它是编写的,我在下面引用
错误响应类型
抛出异常时返回的错误响应 不同于传统命名的{RequestDto}响应DTO 存在与否。
如果存在:
无论服务如何,都会返回{RequestDto}响应 方法的响应类型。如果{RequestDto}响应DTO有 ResponseStatus属性,它被填充,否则没有ResponseStatus 将被退回。 (如果您已装饰{ResponseDto}响应 具有[DataContract] / [DataMember]属性的类和属性 ResponseStatus也需要进行修饰,以便填充。
否则,如果不是:
通过填充的ResponseStatus返回一般的ErrorResponse 属性。
服务客户端透明地处理不同的错误响应 类型,对于像JSON / JSV /等无模式格式,没有实际的 在自定义或中返回ResponseStatus之间的明显区别 通用ErrorResponse - 因为它们都输出相同的响应 丝。
我从上面得到的是我的服务实现中的Delete方法的返回类型是什么?如何在不定义删除响应DTO的情况下实现我的删除方法但是我能够检索“ErrorResponse”n异常信息吗?
路线:
[Route("/DeleteCustomer/{ID}", Verbs = "DELETE")]
public class DeleteCustomer : IReturn<DeleteCustomerResponse>
{
public int ID { get; set; }
}
方法实施:
public DeleteContactResponse Delete(DeleteContact request)
{
.....
}
但每当我使用我的客户端调用此删除时,我总是得到“NotFound”异常。我试过不同的客户但是我得到了404错误。
Servicestack文档中提供的reference link之一可以重复使用“GET”和“DELETE”动词。
另一个link表明并非所有浏览器都支持删除操作。
所以我想知道应该如何实现删除操作?
答案 0 :(得分:13)
有关如何设计REST-ful API with ServiceStack的详细信息,请参阅此前面的答案。
CustomerRestExample包含Customer REST ServiceStack服务的完整独立示例:
以下是典型客户REST服务的自定义路由和请求DTO的示例:
[Route("/customers", "GET")]
public class GetCustomers : IReturn<GetCustomersResponse> {}
public class GetCustomersResponse
{
public List<Customer> Results { get; set; }
}
[Route("/customers/{Id}", "GET")]
public class GetCustomer : IReturn<Customer>
{
public int Id { get; set; }
}
[Route("/customers", "POST")]
public class CreateCustomer : IReturn<Customer>
{
public string Name { get; set; }
}
[Route("/customers/{Id}", "PUT")]
public class UpdateCustomer : IReturn<Customer>
{
public int Id { get; set; }
public string Name { get; set; }
}
[Route("/customers/{Id}", "DELETE")]
public class DeleteCustomer : IReturnVoid
{
public int Id { get; set; }
}
OrmLite POCO模型:
public class Customer
{
[AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
}
基本上,自定义路由标识资源,而HTTP VERB表示对该资源的操作。查看HTTP请求使这一点更加清晰:
GET /customers -> return all Customers
POST /customers -> Create a new Customer
GET /customers/1 -> return Customer 1
PUT /customers/1 -> Update Customer 1
DELETE /customers/1 -> Delete Customer 1
通过上述DTO的定义,我们现在可以通过为每个请求DTO添加实现来实现此Customer REST服务 - 在此示例中使用OrmLite:
public class CustomerService : Service
{
public object Get(GetCustomers request)
{
return new GetCustomersResponse { Results = Db.Select<Customer>() };
}
public object Get(GetCustomer request)
{
return Db.SingleById<Customer>(request.Id);
}
public object Post(CreateCustomer request)
{
var customer = new Customer { Name = request.Name };
Db.Save(customer);
return customer;
}
public object Put(UpdateCustomer request)
{
var customer = Db.SingleById<Customer>(request.Id);
if (customer == null)
throw HttpError.NotFound("Customer '{0}' does not exist".Fmt(request.Id));
customer.Name = request.Name;
Db.Update(customer);
return customer;
}
public void Delete(DeleteCustomer request)
{
Db.DeleteById<Customer>(request.Id);
}
}
通过上述Customer REST Service实施,我们可以重新使用Service Dack与ServiceStack的.NET Service Clients来提供没有代码生成的端到端Typed API,即:
var client = new JsonServiceClient(BaseUri);
//GET /customers
var all = client.Get(new GetCustomers()); // Count = 0
//POST /customers
var customer = client.Post(new CreateCustomer { Name = "Foo" });
//GET /customer/1
customer = client.Get(new GetCustomer { Id = customer.Id }); // Name = Foo
//GET /customers
all = client.Get(new GetCustomers()); // Count = 1
//PUT /customers/1
customer = client.Put(
new UpdateCustomer { Id = customer.Id, Name = "Bar" }); // Name = Bar
//DELETE /customers/1
client.Delete(new DeleteCustomer { Id = customer.Id });
//GET /customers
all = client.Get(new GetCustomers()); // Count = 0
上述注释包括在每个Service Client示例中执行的HTTP操作。
答案 1 :(得分:0)