Open GoogleCodeExporter opened 9 years ago
Hi Mikael,
First of all, thanks for you're interest in this project :)
REST support this is something that I've been thinking about as well and I've
already started to lay down the framework as can be seen in my IRest* service
classes here:
http://code.google.com/p/servicestack/source/browse/#svn/trunk/Common/ServiceSta
ck.Interfaces/ServiceStack.ServiceHost
In there I have interface classes allowing you to specify GET, POST, PUT,
DELETE Http Methods. There is no 'LIST' defined in the spec per-se but you
should still be able to differentiate its intent based on the GET request (i.e.
'Users' vs 'Users/1'). At the moment there is preliminary support for it where
if a service implemented both IService[T].Execute() and IRestService[T].Get()
then GET requests would invoke the 'IRestService[T].Get()' otherwise if
it didn't exist would fall back onto the default 'IService[T].Execute()' the
same with the other HTTP METHODS. Now unfortunately full REST support is going
to require a lot more than this.
For some background info, the 'Service Stack spirit' if you like, are for
requests to be strongly-typed, convention-based, with predictable behaviour
which allows us to provide a simpler API and a lot of functionality for free
without unnecessary configuration whilst still providing good performance. The
challenge therefore is to map the REST world predictably onto a Service Stack
request.
If the REST request was only 1 level deep then this can quickly be applied to a
'ServiceStack request', i.e.
where I could automatically provide support for say:
GET 'Users' => '/SyncReply/Users'
GET 'Users/1' => '/SyncReply/Users?Id=1'
Even at this level, the expected response is 'UsersResponse' which as it needs
to support for both a list and a single 'User' will probably look like:
{{{
public class UsersResponse
{
public List<User> Users { get; set; }
}
}}}
When you go any deeper than that then you are effectively changing the service
you're calling, i.e.
GET 'Users/5/Reports' => '/SyncReply/Reports'
GET 'Users/5/Reports/1' => '/SyncReply/Reports?Id=1&UserId=5'
Now there a clean way you can achieve this today is through 'URL re-writing'
where you would literally just rewrite the query-string to achieve the above
behaviour. The problem with this is the re-writing logic is kept outside of
code in an external web servers configuration file (i.e. nginx or apache),
which is not great productivity win for iterative development. I could also
potentially provide the ability to define your own rules but I'm not 100% sure
what the API would look like (which I would like to know your thoughts on), I
am considering whether it is worth while re-using the URL Routing that comes as
part of ASP.NET MVC e.g:
http://weblogs.asp.net/scottgu/archive/2007/12/03/asp-net-mvc-framework-part-2-u
rl-routing.aspx
Which while we're on the subject, you can kind of in a round-about way build
REST services (well JSON at least) using ASP.NET MVC which as its open source
and included with Mono (Just thought you should know).
I'm still in two minds about whether to go for a new but completely pure /Rest/
endpoint or whether to modify the existing ones to provide richer REST
functionality out of the box. I prefer to modify the existing ones as it will
enrich them with more functionality for free, except as it stands they kind of
violate the 'Accept/Content-Type' HTTP headers as the format is embedded in the
request.
I am more than happy to accept patches the only criteria is that it is a
generic solution to cover most use-cases and it's in-line with 'the Service
Stack spirit' :)
To start the ball rolling, and expedite REST support in ServiceStack it would
be good if you could provide the DTO definition (i.e. request and response
DataContract's) and preferred REST URL's of some of your proposed services
so I can ensure that it can be supported?
As a final word of caution, I should warn you that ServiceStack is still
reliant on Mono's WCF support for SOAP 1.1/1.2 web services, their Base Class
Library DataContractSerailizer for Xml services as well as their
JsonDataContractSerailizer for the JSON ones. In the past they haven't been as
complete as their .NET equivalents and you generally will have to go with the
latest version of Mono to get the best support. They are pretty good
with bug reports so it's quite likely they will fix most issues promptly.
Although as I wanted full source control for a web service implementation that
I can ensure works reliably cross-platform on .NET to .NET endpoints, I ended
up inventing a hybrid JSON + CSV serialization format (i.e. JSV Format)
which has advantages over the above endpoints and you can read more about here:
http://www.servicestack.net/mythz_blog/?p=176
When @marcgravell has finished his rewrite in protobuf-net we'll have another
fully managed/controlled serialization option that as a primary goal will also
work cross-platform.
- Demis
Original comment by demis.be...@gmail.com
on 27 Apr 2010 at 9:40
Hello Demis, I like your service stack library, and in our company we have
written different applications using both REST and SOAP. It would be great to
be able to standardise on one way of doing this though, which is why
servicestack appeals. We do use REST though with DELETEs as well as PUT &
POSTs. We would love to be able to use the full REST functionality - e.g. GET,
PUT, POST & DELETE with servicestack. I see in your post above, you have
implied there is some preliminary support for REST. Is there any way to
implement DELETE today? If so, an example would really help me. And how is work
progressing on REST support in general?
James McGinty
Original comment by james.mc...@gmail.com
on 4 Aug 2010 at 5:10
Hi James,
Sorry for the late reply I've been away for the whole weekend. Yeah I've got
added some fixes and refined the basic support for REST in the latest version
of ServiceStack v1.40 available in the downloads section.
When I get the time I'll write a blog post or article describing the current
REST support, in the time being I've just checked in an example show-casing how
you can handle different HTTP Methods in the latest ServiceStack Example
project or viewable here:
http://code.google.com/p/servicestack/source/browse/trunk/ServiceStack.Examples/
ServiceStack.Examples.ServiceInterface/MovieRestService.cs
I have unit tests here:
http://code.google.com/p/servicestack/source/browse/trunk/ServiceStack.Examples/
ServiceStack.Examples.Tests/MovieRestTests.cs
and Integration tests here:
http://code.google.com/p/servicestack/source/browse/trunk/ServiceStack.Examples/
ServiceStack.Examples.Tests.Integration/MovieRestTests.cs
Yeah I hope to add better REST support in the near future, I think the next
step would be to integrate some sort of 'Route re-writer' similar to the one
found in ASP.NET MVC to map 'pretty REST urls' to the prescribed ServiceStack
urls.
Hopefully this will be enough to get you started, let me know if you have any
questions on how to get started.
Thanks for your interest in ServiceStack.
Regards,
Demis
Original comment by demis.be...@gmail.com
on 10 Aug 2010 at 5:31
Hi James,
FYI I've just checked in an example Ajax page that calls all the
MovieRestService endpoints (i.e. GET POST PUT DELETE):
http://code.google.com/p/servicestack/source/browse/trunk/ServiceStack.Examples/
ServiceStack.Examples.Host.Web/AjaxClient/MovieRestTest.htm
If you get the latest example project you can run the example at:
http://localhost/ServiceStack.Examples.Host.Web/AjaxClient/MovieRestTest.htm
Cheers,
Demis
Original comment by demis.be...@gmail.com
on 11 Aug 2010 at 11:08
I now also have a live example of REST support in ServiceStack:
http://www.servicestack.net/ServiceStack.Examples.Host.Web/AjaxClient/MovieRestT
est.htm
- Demis
Original comment by demis.be...@gmail.com
on 17 Aug 2010 at 7:06
OK Just wanted to update this old thread with pointers to Service Stack's new
REST support. I have now added proper REST support where you can define your
own custom urls using the [RestService] attributes, i.e:
RestService["Users"] => Users
RestService["Users/{UserId}"] => Users/5
RestService["Users/{UserId}/Reports"] => Users/5/Reports
RestService["Users/{UserId}/Reports/{ReportId}"] => Users/5/Reports/1
I got a tutorial and live examples available here:
http://www.servicestack.net/ServiceStack.Hello/Default.htm
- Demis
Original comment by demis.be...@gmail.com
on 12 Dec 2010 at 7:04
Original issue reported on code.google.com by
wikman.mikael@gmail.com
on 27 Apr 2010 at 6:22