Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

As an example, if I have a Post service and have a method to retrieve all posts for the logged in user, is it OK to have a findPosts() method that uses an injected Security service to get the user ID and then pass that user ID to my post DAO to get the records? Or should the findPosts() method explicitly require the user ID as an argument?

share|improve this question

3 Answers 3

up vote 1 down vote accepted

There are differing philosophies, but it very much depends on the context and requirements of your work. If multiple asynchronous connections for different service requests are required to share state that the client should not be aware of then you have few options besides some sort of session management (whether the built-in, or your own based on security tokens or other identification mechanisms). Generally speaking, however, sessions are not necessary nearly as often as they are used and often tend to lead to complications later. Session is volatile, not usually inherently thread-safe, and tied to arbitrary client details in the first place (cookies, IPs, etc.) When you don't control the client Sessions can be unreliable. I could, for example, implement a RESTful GET only client with nothing but raw HTTP requests (which someone else has actually done to me before). As a result common implementation details like cookie persistence become a requirement of your service; this isn't all that uncommon, but the less unnecessary requirements you use the more reliable the clients experiences are.

In general, whenever possible, let the state be directly associated with the individual requests. This allows individual clients more flexibility because your design explains itself and does not depend on hidden features the client won't be able to predict. It also more naturally allows multiple concurrent connections from the same client to have entirely different purposes and state. Let's say their website allows individual user logins and they make calls to your service (API) specific to the individual users; if multiple of their users are using the app at the same time you don't want to force them into a single session if they can just provide you a token with each request or something similar. It can be easy to lose track of state mutations when they are in an invisible background space and, even if the service is simple in the beginning, future additions may not realize something was using session a certain way, etc. etc. Really, this is very much the same as web pages. If you rely on session for page specific operations the user cannot use multiple tabs as it will pollute the state, whereas storing state data in a hidden form field or query string allows each tab to maintain its own state.

Generality aside, there are certainly circumstances that call for it. Distributed computing environments like WCF and other RPC system layers leveraging web services make use of service instance tracking, persistent internal fields, shared context, etc. These features either use Session or at least function very similarly from an abstract perspective. Some people disagree with these methods, but the right tool for the right job should always be the aim.

In your specific case, it sounds like you're really just trying to share authentication state between the browser and async backend requests. Authentication state is frequently sustainable in web services. Particular to authentication, it seems like you should be using security checks even if you received a userId (since it shouldn't just hand that information out to anybody) and since you already have the data it sounds perfectly safe to me (less error/hack prone, since you don't give them the option to tell you which user to use). Alternatively you can receive the parameter specifically to verify that they aren't tampering with the requests, though that only goes so far. Again, just like a web page, sharing authentication between browser tabs is not uncommon, even if the tabs have very different pages loaded, but those pages (or associated middleware) are still responsible for determining what the user can see as well as ensuring the user has the right to be on any specific page.

tl;dr - There are merits to both approaches in this context, including the use of both in tandem. Authentication is commonly shared in web services of differing variety. If these are for Ajax requests then it's especially common. In general, however, only use background shared state when necessary (much like with webpages). The same kind of care goes into deciding what will be static, thread-static, etc. Remember kids: only you can prevent forest fires. KISS

share|improve this answer

Your service should get all the information it needs to do its job in its parameters. If your service is calling something else to get a userID or anything else it needs to generate its return object that is a poor design.

share|improve this answer

It's fine for one service to utilize another service in order to do it's work. That's not a problem. However, if your PostService.FindPosts() method needs a userId, don't pass it a SecurityService, pass it the userId. In fact, you may want to call it FindPostsByUserId() just to be more explicit.

Now, you may have to get the userId from a SecurityService injected into the PostsService, but that's another issue.

share|improve this answer
    
Maybe a bit of context would make it clearer as to why this is a problem. I'm working on a single page app where everything is done through Ajax. Right now, I basically have a front controller ajax.php file that routes all requests to the appropriate service method. I'd prefer not to pass the user ID in the ajax request at all so it can't be tampered with. If I don't do that, then I'd either have to add an extra controller layer to my backend so I can make that get the user ID from the security service and pass it to the other service. But that's a lot of extra code to write for little benefit –  Rocket04 Feb 13 '13 at 16:40
    
I dunno, seems to me like the appropriate amount of code for exactly the benefit you desire (not sending userID in the ajax request). Also highly extensible later, if the need arises. –  Eric King Feb 13 '13 at 16:45
    
I have a grid that I need to get data for. Right now, I already find it repetitive calling my Post service's findPosts method which then calls my Post gateway to retrieve the data. But I can live with it because the service will sometimes need to do more. With controllers, it would become call the controller which calls the service which calls the gateway. And I have a lot of cases like this. Seems like there should be a smarter way. Maybe not so bad if I use my security service, given that my session is abstracted in an object and that interface could be implemented different ways? –  Rocket04 Feb 13 '13 at 16:53

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.