Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Alternative "simple" services implementation
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  9 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
gregmac  
View profile  
 More options Dec 9 2011, 11:57 am
From: gregmac <g...@gregmaclellan.com>
Date: Fri, 9 Dec 2011 08:57:03 -0800 (PST)
Local: Fri, Dec 9 2011 11:57 am
Subject: Alternative "simple" services implementation

Let me start out by saying that I think ServiceStack is a great platform -
it is very well put together and is pretty easy to get up and going with.

One thing I haven't totally wrapped my head around is the philosophy that
every request is a DTO, and that routes map to DTOs, and that there happen
to be services floating around that service the request DTOs. I've seen
some discussion related to that topic but it doesn't address everything:

   - First off, NOT every request is a DTO. This is easily seen in the
   MoviesRest example, where there is an action "ResetMovies". Because of the
   architecture of SS, you have to post an empty ResetMovies DTO (which is
   meaningless).. basically the paradigm doesn't make sense for that type of
   action, at least for me.
   - It's complicated to actually define how a URL maps to code, as you
   have to define the route (where you may optionally specify HTTP verbs),
   connect the route to a DTO, and then define a service for the DTO, and
   finally in that service you have code that handles the request, and can
   optionally handle it differently (or not at all) based on HTTP verb.
   - There is no way (that I have seen so far) to distinguish between a
   parameter passed in the URL and POST/PUT'd as part of the request: If I do
   a PUT to  /users/123  with the object {id:234,name:Test} what am I doing?
   Editing user id 123 or 234? Am I trying to change the id from 123 to 234?

So I could go on about that, but my point is not to complain, just to show
my motivation.

What I am looking for is a way to very easily connect URLs to services.
These may be dealing with DTOs, they may be dealing with actions (such as
ResetMovies).

    [GET("users/{userid}")]
    public UsersResult Load(int userid)

    [PUT("users/{userid}")]
    public UsersResult Edit(int userid, Models.User user)

and so on.

This is conceptual at this point but the idea is the attributes define the
route (you could also do this via regular route definitions, or even by
convention via class/method names like ASP MVC), and the URL parameters are
always passed to the method as well as the posted model, if any.

Compare the code required to have a basic service. svc refers to my
underlying service layer.

ServiceStack existing:

    *[DataContract]*
*    public class UserRequest {
*
*       public int id;*
*    }*
    public class UserService : *RestServiceBase<UserRequest>* {
        public MyServiceLayer.Service svc { get; set; }
        *public override object OnGet(UserRequest user) {*
*            return svc.LoadUser(user.id);*
*        }*
    }

    .... and elsewhere in global.asax...
    Routes*.Add<UserRequest>("/users/{id}", "GET");*

Proposed:

    class UserService : SimpleRestService {    // ?
        public MyServiceLayer.Service svc { get; set; }
        *[GET("users/{userid}")]*
*        public UsersResult Load(int userid) {*
*           return svc.Load(userid); *
*        }*
    }

I bolded what is in my opinion the non-boilerplate code.

I'm willing to put energy into developing this on top of SS, but am I
missing something? Is there a reason this is a terrible idea? Am I
committing some sin against REST?

I am considering this as an extension on top of SS or an alternative
built-in method (depending if it gets accepted into the project), not a
total replacement for the existing interface.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Demis Bellot  
View profile  
 More options Dec 9 2011, 12:56 pm
From: Demis Bellot <demis.bel...@gmail.com>
Date: Fri, 9 Dec 2011 12:56:40 -0500
Local: Fri, Dec 9 2011 12:56 pm
Subject: Re: [ServiceStack] Alternative "simple" services implementation

Hi gregmac,

Thanks for your feedback.

I try to promote a single message-based DTO approach to designing and
invoking services.
There is major usability and re-usability advantages by having every
service accept a Request DTO and conversationally returning a Response DTO
(with Results and Exceptions in predictable properties).

This has major ripples through the entire use and design of your services
from understanding how each service behaves, usage by your Service Clients,
being able to proxy/delegate or drop your Request DTO into a sub-service or
MQ for async message processing etc.

Basically leaving everything as 'Message based' is a powerful concept that
I will be keeping, as soon as you start to map Web Service Calls to an RPC
method signature you are no longer 'sending a Request DTO' to a service,
you're instead trying to invoke that particular method signature - it
becomes much more tightly coupled and you're ability to evolve that service
becomes hindered as any changes on the server effectively means the client
needs to change as well and marshaling to a Method signature tends to mean
you'll need to have client code-gen in order to provide a typed, succinct
API. You'll also need to do this for every service client you want to
support (i.e. JSON/XML/JSV/MQ/etc) unlike the elegant approach of the
generic Service Clients bundled with ServiceStack.

Code-gen is another one of my major dislikes and IMO should be avoided
where possible, it becomes an arthritis in your system and you start to
become a slave to your tooling - In my experience code-first produces
simpler more elegant and maintainable solutions then code-gen.

So whether you have 0 properties, 1 property or 20 properties they all work
the same way and IMO there is not much boilerplate in doing:

> public class ResetMovies {} for an empty DTO.

If you prefer the RPC approach for services you should easily be able to
implement this in a base-class using your own attributes / conventions
where you marshal the Request DTO to your sub class method calls (likely
the approach you're thinking about already).
If there is strong demand by others in this group I can include your base
class into ServiceStack.ServiceInterface.dll so it's an optional feature
they can choose to use or not.
Otherwise of course the other option is to host ServiceStack with MVC or
NancyFx and use they're routing system when it makes more sense to.

It's complicated to actually define how a URL maps to code

There are 2 ways to map a Route with your Request DTO it sounds like you
would prefer the 2nd option, where the route is more cohesively kept with
your Request DTO e.g:

[RestService("/users/{Id}")]

> public class Users { ... }

Personally I think the convention of not specifying the Verb means it
applies to all HTTP Verbs is an acceptable default convention that's
natural to assume.

There is no way (that I have seen so far) to distinguish between a

> parameter passed in the URL and POST/PUT'd as part of the request:

You can either have 2 Id Properties for cases when you think they will be
different (personally I think this is situation should be rare):

[RestService("/users/{ForId}")]

> public class Users { int ForId, int Id, ... }

Or alternatively inspect the HttpRequest to determine which Id was passed
in the Request Path, i.e:

var httpReq = base.RequestContext.Get<IHttpRequest>();

httpReq.Path; //httpReq.AbsoluteUri, etc.

There's a couple of things I would do differently, here's my version:

[RestService("/users/{Id}")]
[RestService("/users/{Id}/{Method}")]  /* [DataContract] not needed, Drop
Request suffix */
public class Users {
public int Id { get; set; }
public string Method { get; set; }

}

public class UserService : RestServiceBase<Users> {
public MyServiceLayer Svc { get; set; }

public override object OnGet(Users request) {
if (request.Method == "load")
    return Svc.LoadUser(request.Id)
...

}
}

i.e. I would leave off any 'Request' or 'Dto' suffix on your Request DTO as
I like to consider the Request DTO *is* the contract/API for your service
and what you should be referring to when you talk about it (i.e. the
Service implementation should be remain an implementation issue :)

I am considering this as an extension on top of SS or an alternative

> built-in method (depending if it gets accepted into the project), not a
> total replacement for the existing interface.

If you're more comfortable with this approach then I see no harm in
developing this even if it's just for yourself (a lot of the features in
ServiceStack is to scratch my own itch as well).
Personally I wont be using this feature since I don't think the boilerplate
reduction justifies the added delegation/complexity and less debuggability
but if there is a strong demand for this I can include it in the
ServiceStack.ServiceInterface project.

Hope this helps clarify some of the philosophy behind ServiceStack.

Cheers,

--
- Demis

http://twitter.com/demisbellot
http://www.servicestack.net/mythz_blog


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
gregmac  
View profile  
 More options Dec 11 2011, 9:10 pm
From: gregmac <g...@gregmaclellan.com>
Date: Sun, 11 Dec 2011 18:10:57 -0800 (PST)
Local: Sun, Dec 11 2011 9:10 pm
Subject: Re: [ServiceStack] Alternative "simple" services implementation

Hi Demis,

On Friday, 9 December 2011 12:56:40 UTC-5, mythz wrote:

> I try to promote a single message-based DTO approach to designing and
> invoking services.
> There is major usability and re-usability advantages by having every
> service accept a Request DTO and conversationally returning a Response DTO
> (with Results and Exceptions in predictable properties).

> This has major ripples through the entire use and design of your services
> from understanding how each service behaves, usage by your Service Clients,
> being able to proxy/delegate or drop your Request DTO into a sub-service or
> MQ for async message processing etc.

So what you're saying is that keeping each request as a single DTO
simplifies the use of certain patterns on the clients, such as using a
queue.  Okay, I will somewhat buy that, but the client still needs to know
the URL to send the DTO to..

> Basically leaving everything as 'Message based' is a powerful concept that
> I will be keeping, as soon as you start to map Web Service Calls to an RPC
> method signature you are no longer 'sending a Request DTO' to a service,
> you're instead trying to invoke that particular method signature - it
> becomes much more tightly coupled and you're ability to evolve that service
> becomes hindered as any changes on the server effectively means the client
> needs to change as well and marshaling to a Method signature tends to mean
> you'll need to have client code-gen in order to provide a typed, succinct
> API. You'll also need to do this for every service client you want to
> support (i.e. JSON/XML/JSV/MQ/etc) unlike the elegant approach of the
> generic Service Clients bundled with ServiceStack.

I don't understand what you're saying here. What in the SS pattern prevents
the client from needing to change if the server changes? As far as I can
tell, the client still has to know the URLs, and still has to know the DTO.

If you change the URL endpoint on the server, the client has to change --
so I'm failing to see why my proposed pattern is any different. In existing
SS and what I'm proposing, you can make a change to the server that
requires the clients to change, and you can also do some changes that are
backwards compatible.

> So whether you have 0 properties, 1 property or 20 properties they all
> work the same way and IMO there is not much boilerplate in doing:

>> public class ResetMovies {} for an empty DTO.

I don't have any problem with the DTO boilerplate directly. What I find
awkward is the connection between the DTOs, services, and routing. I
consider the URL and HTTP verb to be effectively one and the same, so what
bugs me is the fact that the URL is defined by routing, and the verb is
defined by the service code implementation (and also, possibly, the
routing). On top of that, the service is not connected directly to the
routing -- it's connected implicitly via the DTO.

> If you prefer the RPC approach for services you should easily be able to
> implement this in a base-class using your own attributes / conventions
> where you marshal the Request DTO to your sub class method calls (likely
> the approach you're thinking about already).

To be clear, I'm not trying to do an RPC approach. I think the difference
is that I like to think of the URL first (or in other words, the API of the
service). I want direct control of how the URL maps to handler code. With
the current SS implementation, I feel like the URL is a by-product of
everything else, because it's so convoluted to connect to the handler code.

To illustrate this, I think: "Ok, I want GET /movies to be a list of all
movies, POST /movies to add a new movie, GET /movies/{id} to load a single
movie, PUT /movies/{id} to edit that movie, and POST /movies/reset to reset
the sample database."  Arguably /movies/reset is RPC-style, but it's
inevitable that you'll eventually want to tell the server to do actions,
and personally I feel that is still a RESTful way to do it.

In SS now, I have to now do a second step. For each distinct request, I
need to think about what the request DTO is going to be, and then I have to
map that DTO to a URL. Then, I have to go back and map each request DTO to
the IService that can handle it.

> It's complicated to actually define how a URL maps to code

> There are 2 ways to map a Route with your Request DTO it sounds like you
> would prefer the 2nd option, where the route is more cohesively kept with
> your Request DTO e.g:

> [RestService("/users/{Id}")]
>> public class Users { ... }

> Personally I think the convention of not specifying the Verb means it
> applies to all HTTP Verbs is an acceptable default convention that's
> natural to assume.

Yeah sorry, I should have pointed this out in my example since it is closer
to what I was showing.  I do agree, in this design, not specifying a verb
having the meaning of all verbs is very natural.

In my opinion, both of these methods are total hacks. In the first method,
you STILL have the same problem -- what happens when a client specifies
ForId as part of the request DTO and the URL? Actually that is a rhetorical
question - it doesn't matter, because as a user of servicestack, there is
no clear answer. I'd have to read the SS code and/or documentation, or
figure it out by trial and error. I am suggesting there is a better API
that removes this ambiguity, and makes a natural and supported way to get
at these properties.

verb in the URL. I know it's somewhat hypocrtical of me to say this after
suggesting "/movies/reset", but there is no HTTP verb for "reset all
movies", while there is a verb for load (GET).

I also really don't like having (request.Method == "load") in the service
code. It feels to me like the framework only did 80% of the work it should
have - it mapped the request object into service code by looking at the URL
and mapping parameters, but then it left the final 20% up to the service
implementation. It just seems like this is something that the framework
should do for you, the actual code a user of the framework should write
should be pure service implementation -- leave the mapping of the request
to my code up to the framework.

I am considering this as an extension on top of SS or an alternative

It does somewhat, but I don't really get the full motivation yet. Since no
matter what, you're still tied to the URL, any attempt to abstract that
away actually seems counter-intuitive.

In the end, I'm just looking to simplify mapping between URLs and service
code. What I was hoping to get out of this thread is an understanding of
why having a DTO is beneficial, but so far I don't get it. You briefly
mentioned using queues, and I think were hinting at abstracting away the
implementation (which I guess means the URLs the client points at?) but I
fail to understand how it's possible to have the client ignore the URL, and
why knowing the URL (and even having parameters in it) cause any problems
on either the client or server. Is there an example somewhere you can point
me at, where it's clear that the single request DTO is beneficial, and it's
not possible to do it using my proposed code?

Am I still completely missing something here?

Thanks,
Greg


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Demis Bellot  
View profile  
 More options Dec 12 2011, 1:25 am
From: Demis Bellot <demis.bel...@gmail.com>
Date: Mon, 12 Dec 2011 01:25:01 -0500
Local: Mon, Dec 12 2011 1:25 am
Subject: Re: [ServiceStack] Alternative "simple" services implementation

Firstly I want to point out the patterns and core ideas ServiceStack is
based around and tries to promote - they are all short but highly
recommended reading.
Here are the very few patterns I follow and find fundamentally important
when developing web services, which are strangley enough also available on
the MSDN <http://msdn.microsoft.com/en-us/library/ff649585.aspx>
website<http://msdn.microsoft.com/en-us/library/ff650101.aspx>but for
whatever other reason is discouraged by WCF:

  - Remote Facade
Pattern<http://martinfowler.com/eaaCatalog/remoteFacade.html>-
Promoting the design of coarse grain and batchful interfaces whenever
you
communicate across process boundaries.

  - DTO pattern
<http://martinfowler.com/eaaCatalog/dataTransferObject.html>- Special
purpose POCOs that define your web services payloads.

  - Service Gateway
pattern<http://martinfowler.com/eaaCatalog/gateway.html>- To
encapsulate your client and server communications.

I also believe these patterns promote 'web service development best
practices' that better lend themselves in designing SOA systems as it leads
to fewer, less client-specific and more re-usable services. I've created a
small gist to show the contrast between the RPC methods that I believe WCF
encourages and the equivalent services I hope to encourage with
ServiceStack:
https://gist.github.com/1386381

The above gist also shows you how you can easily add extra service
functionality to the Request DTO and data to the Response DTO in a way that
doesn't effect old/existing clients as the extra functionality/data just
gets ignored by unaware clients. The JSON and JSV endpoints and serializers
are extremely resilient and can withstand some extreme versionability of
your services without
error<https://github.com/ServiceStack/ServiceStack.Redis/wiki/MigrationsUsi...>
.

The above patterns (and many more) are discussed in detail in Martin
Fowlers excellent Patterns of Enterprise Application
Architecture<http://www.martinfowler.com/books.html#eaa>
.

> So what you're saying is that keeping each request as a single DTO
> simplifies the use of certain patterns on the clients, such as using a
> queue.  Okay, I will somewhat buy that, but the client still needs to know
> the URL to send the DTO to..

ServiceStack automatically exposes Sync and Async Urls for each of your web
services (see: "*The different ways of calling your Web Service*" in
http://www.servicestack.net/ServiceStack.Hello/)
This lets you provide a base url into any ServiceClient which lets you call
each web service. Here's a Unit/Integration Test example that allows the
same unit test to be executed by all ServiceClients using the same Base
Url. No custom routes were needed:

https://github.com/ServiceStack/ServiceStack/blob/master/tests/Servic...

This is effectively impossible to achieve if you had used code-gen clients,
which lets you bind to an implementation-free IServiceClient that allows
you to switch formats (ServiceClients) at anytime without any rewrites
required.

The custom routes are there if you want to provide REST-ful canonical urls
for all your services if you prefer - though it's entirely optional and not
needed by default.

I don't have any problem with the DTO boilerplate directly. What I find

> awkward is the connection between the DTOs, services, and routing. I
> consider the URL and HTTP verb to be effectively one and the same, so what
> bugs me is the fact that the URL is defined by routing, and the verb is
> defined by the service code implementation (and also, possibly, the
> routing). On top of that, the service is not connected directly to the
> routing -- it's connected implicitly via the DTO.

Yes this is the ServiceStack idiom where the *Request DTO* is your service
- it defines the contract and is all you need to identify and invoke it. So
in ServiceStack the Request DTO == Your service, which is why I suggest you
make it a first-class concept and you drop any 'Request' suffix you might
have as the Request DTO is your code-first contract and everything else
hangs off it.

I personally don't like this at all. This now looks like RPC: you have a

> verb in the URL.

You may not like it but it's extremely intuitive as to which method gets
invoked via each HTTP Verb. The only difference between inheriting from
ServiceBase and RestServiceBase is that ServiceBase.Run() gets invoked for
every HTTP verb on any endpoint with any format, etc whilst
RestServiceBase.OnGet()/OnPost() etc will execute different methods based
on the HTTP Verb which is ultimately what you want when you're implementing
a REST-ful api.

I also really don't like having (request.Method == "load") in the service

> code. It feels to me like the framework only did 80% of the work it should
> have

Up to this point is where ServiceStack marshals the request into a C#
Request DTO (via any endpoint, format or calling convention) is the bottom
most point where it works naturally as expected, any further then it starts
to become opinionated, you lose debuggability and "magic behaviour" starts
to occur. Like I've articulated I dislike marshalling to a RPC method
signature as I think it promotes the wrong service API design and
implementation also once you lose the Request DTO you start to lose your
ability to cleanly defer, proxy or cache the request.

It does somewhat, but I don't really get the full motivation yet. Since no

> matter what, you're still tied to the URL, any attempt to abstract that
> away actually seems counter-intuitive.

You're not tied to the url if you use the auto generated routes (i.e. you
only need supply the base url). If you're just doing a client/server app
where you provide an .NET client gateway that wraps your services i.e. the
client never sees the custom url routes then I don't believe you should
have any as it just adds an extra layer of un necessary 'industrial
knowledge' i.e. more friction / work that needs to be done and that can get
out of sync with your services.

In the end, I'm just looking to simplify mapping between URLs and service

> code.

You should be able to provide the custom Url routing using the attributes
and conventions you prefer with your own base class. And like I said
earlier if there is strong demand for this I can include as an opt-in, in
the framework.
By letting you do it (and not the framework) you get debuggability on the
area which I believe will prove problematic and other users that don't like
this indirection (i.e. me) needn't suffer the additional perf overhead for
a feature they don't use.

What I was hoping to get out of this thread is an understanding of why

> having a DTO is beneficial, but so far I don't get it. You briefly
> mentioned using queues, and I think were hinting at abstracting away the
> implementation (which I guess means the URLs the client points at?) but I
> fail to understand how it's possible to have the client ignore the URL, and
> why knowing the URL (and even having parameters in it) cause any problems
> on either the client or server. Is there an example somewhere you can point
> me at, where it's clear that the single request DTO is beneficial, and it's
> not possible to do it using my proposed code?

All the HTTP Service Clients in ServiceStack:
https://github.com/ServiceStack/ServiceStack/tree/master/src/ServiceS...
including the non-HTTP Messaging, Redis MQ and RCON clients can invoke a
service with just the Request DTO, it can do so providing a typed API
without any code-gen simply because everything hangs off the Request DTO
which maps 1:1 with your service. For better or worse the Request DTO *is
your service interface* you will have a lot less time fighting the
framework if you follow this single fundamental convention.

 I fail to understand how it's possible to have the client ignore the URL

All HTTP Service Clients use the auto provided urls as documented in
ServiceStack.Hello <http://www.servicestack.net/ServiceStack.Hello/> to
invoke any of your services with just your services BaseUri as seen in
Integration
and Unit test examples<https://github.com/ServiceStack/ServiceStack/blob/master/tests/Servic...>
.

You can defer the execution of your service for an instant response time
and added reliability/durability by dropping it in a MQ like:

using (var producer = MessageFactory.CreateMessageProducer()) {
producer.Publish(request);

}

So far the Messaging Service API in ServiceStack has an InMemory,
Redis-backed MQ and TCP/RCON implementations with a very extensible
interfaces so you can provide your own MQ adapters.

In order to archive, log or reconstruct the request for later playback you
only need to serialize (and playback) the Request DTO - this is impossible
to do elegantly if you mapped to an RPC method signature.

Likewise to delegate/proxy the request to a Sub System (e.g. Master>Shards)
you could easily do it with something like:

public override object Run(Users request) {
var shardClient = this.ShardClients[request.UserId % ShardsCount];
return shardClient.Send<UsersResponse>(request);

}

Basically ServiceStacks 'message-based' approach allows you to solve many
high-level messaging integration patterns more elegantly than an RPC
approach.
It increases productivity since there is no code-gen, increases the
re-usability and versionability of your services and the added boiler plate
should really be inconsequential since you should have less but more
coarse-grained/batchful services.

Hope this helps explain the philosophy behind ServiceStack further :)

Cheers,

...

read more »


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
M. David Peterson  
View profile  
 More options Dec 14 2011, 11:09 pm
From: "M. David Peterson" <m.da...@3rdandurban.com>
Date: Wed, 14 Dec 2011 20:09:34 -0800
Local: Wed, Dec 14 2011 11:09 pm
Subject: Re: [ServiceStack] Alternative "simple" services implementation

On Fri, Dec 9, 2011 at 9:56 AM, Demis Bellot <demis.bel...@gmail.com> wrote:
> Personally I think the convention of not specifying the Verb means it
> applies to all HTTP Verbs is an acceptable default convention that's
> natural to assume.

Not to mention absolutely critical to the foundation of a REST-based
architecture.  One of primary reasons I chose to fully embrace ServiceStack
2+ years ago as a core part of our architecture was because Demis was
adamant about keeping the library firmly founded on a true REST foundation
where everything is a resource represented by a distinct URI endpoint in
which CRUD operations are specified using the built-in architecture of the
web in HTTP(S) verbs.

If you start thinking of DTO's in the same sense that you think of any
other resource on the web, placing the focus on Creating, Reading,
Updating, and Deleting that resource via passing (potentially) modified
copies of that same resource between client and server (and therefore fully
embracing the stateless nature of the URI-centric HTTP architecture) it
then becomes a lot easier to either fully embrace (or fully reject) the
REST-based DTO-centric focus of ServiceStack. That doesn't mean that
choosing not to embrace the ServiceStack approach is absolutely wrong. It
just means that your application needs are likely not a good fit with the
ServiceStack approach.

--
/M:D

M. David Peterson
Co-Founder & Chief Architect, 3rd&Urban, LLC
Email: m.da...@3rdandUrban.com
Voice: (801) 742-1064
http://amp.fm | http://mdavidpeterson.com


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ethan Brown  
View profile  
 More options Dec 15 2011, 1:09 pm
From: Ethan Brown <ethan.j.br...@gmail.com>
Date: Thu, 15 Dec 2011 10:09:37 -0800 (PST)
Local: Thurs, Dec 15 2011 1:09 pm
Subject: Re: [ServiceStack] Alternative "simple" services implementation

Greg -

As an addendum to everything that's been said, REST purists (by way of Roy
Fielding) will promote HATEOAS, which is essentially an additional layer of
indirection between the entry point of your API, and the actual resource
URIs.  So to your point about mapping to URIs, clients *can* be insulated
from actual Resource URIs if you take a HATEOAS style approach.  

Unfortunately, there isn't great tooling for that architectural style, it
adds an additional complexity burden on the client, potentially adds extra
chattiness (if you don't implement caching semantics properly), and it
isn't something you'll see a lot of in the wild for real world examples,
etc.  See this SO search for some examples and some of +s / -s to HATEOAS
(including a few examples like Suns Cloud API):
http://stackoverflow.com/search?q=HATEOAS

Demis isn't a fan and AFAIK, SS doesn't support this out of the box (please
correct me if I'm wrong Demis!)
http://www.servicestack.net/mythz_blog/?p=665
You could roll your own for basic scenarios, and you could probably find a
reasonable way to do this generically since services are registered in the
top level IoC container, but only your environment will determine if
there's any real value. YAGNI and all that...

You might also find this interesting as it talks about HATEOAS wrt
versioning:
http://www.mnot.net/blog/2011/10/25/web_api_versioning_smackdown

There is this Ruby / Java / .NET client that does HATEOAS (not to steal any
thunder away from SS!).  I've never used it, but if that's a better fit for
what you're looking to do, have a look.
http://restfulie.caelum.com.br/

-e


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Demis Bellot  
View profile  
 More options Dec 15 2011, 3:52 pm
From: Demis Bellot <demis.bel...@gmail.com>
Date: Thu, 15 Dec 2011 15:52:58 -0500
Local: Thurs, Dec 15 2011 3:52 pm
Subject: Re: [ServiceStack] Alternative "simple" services implementation

Right,

I'm not a fan of HATEOS which is basically just an imposed set of
restrictions forcing you to be more abstract and do more work than you
otherwise would, it also promotes the idea of dumb/server-driven clients -
which will always produce a slower UX, containing more round trips with a
generic un-optimized interface for the task at hand.
This basically fails Comp-Sci 101 where the more generic and abstract you
make something the more complex it becomes and the less useful it is.

In my opinion it's a complete pipe-dream that you can have truly autonomous
systems where you can roll in new behavior and existing clients can
automatically take advantage of it.
It's an un-fulfilled idealistic dream that you can just simply add a new
system module (i.e. Ordering system) and existing clients (without updates)
can just take advantage of it without having any out-of-band knowledge of
it, I could only see it working if everyone adopts universal schemas for
new functionality - but in the real word we know this doesn't happen. I've
never seen/heard HATEOS work in true B2B systems (where there is no human
on the client side inferring and acting on the new rel types / intents).

The other big problem is that it imposes a 'single view' of your system,
i.e. the server view - which effectively forces all clients to work and
behave exactly the same way.
If you adopt it, you become 'locked in' to this restrictive system work
flow where you can potentially only access a new feature if you transition
to it from the 'previous states' up in the heirachy.
Also it's much harder to participate in a heterogeneous environment
accessing services that doesn't implement the same HATEOS service
implementation, i.e. I think you'll find it extremely rare to have a client
talking to 2+ independent HATEOS systems that weren't developed by the same
team.

This is in contrast to the SOA mindset where you should strive to expose
your new capabilities in as interoperable / accessible way possible so it
becomes trivially accessible for any client to consume which they can do in
any way they see fit.

The best HATEOS-like system and client you'll likely ever to see is your
standard client browser navigating HTTP/HTML websites - where we have
optimized web frameworks and development tools for building.
It's infinitely more usable, accessible and stands the best chance of
working on all platforms with zero effort of develop HATEOS clients for
every platform you wish to support.

Nope not for me, in the end I believe HATEOS was conceived at a time before
you can update your clients with an F5. No self-respecting company wanting
to provide amazing end-user experiences - it just exists so Cargo cults can
waste time Hi 5'ing each other for their attempts at flexing REST theory
and getting there CONNEG solution to work. This is the same joy WCF devs
get when they've discovered the perfect combination of WCF configuration to
get there single service to work in XML, JSON and SOAP at the same time! -
meanwhile ServiceStack has been shipping this and more in the default
install for years at much better performance.

Personally lifes too short to waste time on fighting frameworks /
configuring infrastructure and implementing idealistic impractical system
theory that produces sub-par experiences.

In order to shield myself from wasting valuable brain cell space learning
dead tech/philosophies like this - I look to to companies I respect that
heavily research into what ultimate solution delivers the best end-user
experience - So if Google, Apple, Amazon, etc aren't using it (which your
services stand no chance in matching in breadth or size) then there's a
good possibility that you shouldn't either.

Having said this there are a few good ideas in HATEOS, namely to make your
services/API more discoverable, although this doesn't need any kind of
'special or explicit' support to achieve, it simply just involves dumping a
list of relevant urls/states (see: BS. REST term from elitist handbook) at
the end of your Response DTO. Although I only expect this to be useful for
improving the service/API documentation for developers consuming your
service at development time, which although is still important, is much
less in scope of what HATEOS envisages.

I apologize for the morbid tone of this post but I dislike seeing
inefficiencies propagated by devs blindly following advice on developer
philosophers (who don't ship real-world systems) without understanding
the true benefits of their tech choices so they can assess it for
themselves in their own context on its own merits as to whether or not it
actually promotes a more productive / maintainable system producing a
superior UX - my belief is that in most use-cases it wont - and that the
primary motivation for imposing their clients to this tech debt is so they
can stay stay subscribed to their REST/HATEOS Cargo Cult  - that needless
to say I have personally have no wish to be apart of.

Regards,

On Thu, Dec 15, 2011 at 1:09 PM, Ethan Brown <ethan.j.br...@gmail.com>wrote:

--
- Demis

http://twitter.com/demisbellot
http://www.servicestack.net/mythz_blog


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ethan Brown  
View profile  
 More options Dec 16 2011, 4:44 pm
From: Ethan Brown <ethan.j.br...@gmail.com>
Date: Fri, 16 Dec 2011 13:44:47 -0800 (PST)
Local: Fri, Dec 16 2011 4:44 pm
Subject: Re: [ServiceStack] Alternative "simple" services implementation

I struck a nerve!

I wasn't promoting HATEOAS, just giving Greg options since he seemed
uncomfortable with URI contracts.  

You should know by now I'm on board with the SS philosophy and a huge fan!
;0

To take this in another direction -- seen the eBay orchestration framework
ql.io?
http://ql.io/

At first take it seems rather awkward / a bandaid for systems with poorly
designed APIs, but I haven't had the time to really dig in.  It definitely
feels... weird.

-e


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Demis Bellot  
View profile  
 More options Dec 16 2011, 5:25 pm
From: Demis Bellot <demis.bel...@gmail.com>
Date: Fri, 16 Dec 2011 17:25:19 -0500
Local: Fri, Dec 16 2011 5:25 pm
Subject: Re: [ServiceStack] Alternative "simple" services implementation

Hey Ethan,

My response is not directed at anyone here - I just have a dim view of
influential devs chasing and preaching over-architecture nirvana but never
delivering a compelling end user result.
The amount of waste and tech debt that blindly following the 'party line'
creates is disheartening and unfortunately I've seen a lot of millions and
many man years wasted in overarchitected systems that never ship because
they blindly follow 'so-called consultant' advice promising technical
nirvana.

Anyway I purposely went a little overboard so my views were engraved on
this thread and it would last through the ages :) Oh and I can link to it
when others ask for my views on it :).

Yep I've looked at ql.io it reminds me a lot of oData / IQueryable - Great
for adhoc reporting but because it implies a specific implementation it has
a way of locking down your system from further changes in a similar way
that exposing your internal connection to other systems string would do
(i.e. you'd have to make sure that none of your changes to your db schema
would break the existing apps accessing your db). If instead all API access
happened via the service layer you have complete freedom to make any change
to your internal datastores as you know what the external API your clients
have binded to.

A great REST idea is to have (impl-agnostic) canonical urls for your
resources as it stands the best chance to not break any links even after a
complete rewrite of your service, because any new impls would just need to
naturally implement the canonical urls.

Cheers,

On Fri, Dec 16, 2011 at 4:44 PM, Ethan Brown <ethan.j.br...@gmail.com>wrote:

--
- Demis

http://twitter.com/demisbellot
http://www.servicestack.net/mythz_blog


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »