I am working with several external APIs on a business code that would be used by several developers that do not have the deep knowledge required to build meaningful queries to those APIs.
Those API retrieve data. For example, you can retrieve entities either based on their Key (direct access) or based on their Group (lists available entities). But if you choose to query by Key you have to provide an id, and if you query by Group you have to provide a groupName.
The APIs are bigger than that and more complex, with many possible use-cases. The main constraints are that:
Some parameters require the presence of other parameters
Some parameters put with other parameters produce no data at best, wrong data at worst.
I would love to fix the underlying APIs but they are outside our scope.
I think it might be good to enclose a bit those API and produced a APIService that can request(APIQuery query).
The basic thing I could do is to put conditions in the code to check that no developer instantiates the APIQuery with missing/incoherent parameters, however that would only be a runtime error. I would love for the developer to know when building their request that they can/cannot do something.
My two questions are:
Is there an extensible builder-like way to defer the responsibility of building itself to the object? Having 1 constructor per valid query is not a good solution, as there are many variables and "unspoken rules" here.
Is this even a good idea? Am I trying to over-engineer?
I'll answer your second question first:
Is this even a good idea? Am I trying to over-engineer?
The answer is an uncomfortable "it depends". It depends how bad the pain is, it depends how crucial it is to get this right. It depends on so many factors that we can't really tell.
And to your: is this possible?
Yes, a builder pattern can be extended to return specific builders when certain methods are called, but this can become complicated and mis-uses are possible.
For your specific example I'd make the QueryBuilder simply have two methods:
a byGroup method that takes a group value to filter on and returns a GroupQueryBuilder
a bykey method that takes a key value to filter on and returns a KeyQueryBuilder.
Those two classes can then have methods that are distinct to their respective queries and possibly extend a shared base class that provides common properties.
And their respective build methods could either return a APIQuery or distinct APIQueryByGroup/APIQueryByKey classes, whichever is more useful for you.
This can become way more complicated if you have multiple axis upon which queries can differ and at a certain point, it'll become very hard to map that onto types.
Related
I'm trying to write a REST interface to manage one of the resources in my application. Following best practice only I want to only use nouns as resource names.
I need the ability update the resource (a PUT operation) in one of several different ways. I imagine my user would call something like:
/resource/{name}?Operation=DO&time=1&Unit=HOUR
/resource/{name}?Operation=REDO&time=1&Unit=HOUR
/resource/{name}?Operation=UNDO
(I'll probably have more then 3 operations, but this is enough to show what's going on). One of the important things that the operations have different arguments. Logically time and Unit do not make sense to the UNDO operation.
In my Java back end I'd like to implement this with two different methods each of which will have it's own #RequestMapping annotation. The differentiator will be the value of the Operation parameter. I can't find any documentation that tells me how to do this
The alternative is to have a single method at the backend, but this is really ugly as I'll have to work out what combination of parameters is valid and throw my own 404 errors if they don't match!
If you absolutely need 2 controllers then do something like
/resource/do/{name}/{time}/{unit}
/resource/undo/{name}
I need to make a couple of services that will talk to both Amazon S3 and Riak CS.
They will handle the same operations, e.g. retrieve images.
Due to them returning different objects, in S3's case an S3Object. Is the proper way to design this to have a different class for each without a common interface?
I've been thinking on how to apply a common interface to both, but the return type of the methods is what's causing me some issues, due to them being different. I might just be going wrong about this and probably should just separate them but I am hoping to get some clarification here.
Thanks all!
Typically, you do this by wrapping the responses from the various external services with your own classes that have a common interface. You also wrap the services themselves, so when you call your service wrappers they all return your wrapped data classes. You've then isolated all references to the external service into one package. This also makes it easy to add or remove services.
A precise answer to your question would require knowing the language you are using and/or the platform. Eric in his answer above is correct that wrapping the data inside one of you own class is one way to handle this. However, depending on the language, the details of the final implementation will vary and the amount of work required when adding possible return value type will also vary.
In Java for example one way to handle this would be to return an heterogeneous container. Take a look at this thread:
Type safe heterogeneous container pattern to store lists of items
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
Designing application tier is not trivial. At the end of the day, in every project we write (huge) number of so-called business methods (sometimes called service methods, although it is not related to services as in public APIs) that perform some business logic and usually do some database/storage operations (via storage tier). But designing/organizing/naming your application methods is not trivial as it sounds; people often have rules on project how application classes and methods should be designed. I am looking for pragmatic set of such rules for designing the application tier, so here are some questions:
Grouping methods in classes: by return type or?
For example, method that updates a user belongs to class eg UserService. Or method that finds a user by some criteria belongs to the same class. But what happens when some method works on several types, like e.g. registerUserForCompetition()? Should this be in UserService or CompetitionService? The same question for the method findUserCompetition() - where would you put it?
I often see a rule that says that this depends on methods return type. In our example, if method returns User (or collection of users etc) it should belong to UserService.
Method parameters: simple types (primitives, String...) or entities (e.g. User, Competition, Registration...)?
This question is often asked, and people usually (statistically:) choose the first approach, using simple types as service arguments. But what to do when one such method calls the other method on the same resource? Let me give you an example: registerUser(userId, competitionId) may internally call checkCompetition(competitionId). Both methods fetch the Competition from the storage. Obviously, this is done twice and, since we already have the Competition object we can use it to checkCompetition with it. So should we add overloaded method, or we should ignore this and just really on caching mechanism to prevent double fetching?
On the other hand, having full types as parameters can not be universal rule, as many times the full information is not needed and there is no reason to fetch the full object while you need just it's id, that you already may have it.
Naming methods: how verbose methods name should be?
Especially for finder methods. Should we have eg:
findCompetition(userId, year) or
findCompetitionWithVenue(userId, year) (since every Competition object has linked Venue); or
findCompetitionForUserAndYear(userId, year) or
findCompetitionByUserIdAndYear(userId, year) or just
findUserCompetitionForYear(userId, year)?
When number of different criteria rises, it is easy to make a mess with finder method names, and I often see rules like this: find<return-type>By<names-of-parameters> or similar.
Do you have naming convention for application classes?
Do your classes names end with Service? Do you separate managers from services, where manager deals with entities and services accept only simple types? Do you group all your business classes in the same package, or group them together with other related classes (model, controller...), based on functionality?
Please share your experience with focus on being pragmatic - for me it means that new developer can easily figure where to find business methods and how to write new ones, so everyone gets more productive. Also, if you have established rules, please share how your team is managed to follow them.
group services by functionality. in the same package should be also controler, part of model etc. there are better approaches then layered architecture. try DDD. it perfectly isolates functionality, makes it easier to find and change
usually it's good to have entities (model) hidden from the client and communicate with controllers through DTOs and ValueObjects. just in case you want to change your model in the future
they must be meaningful for your domain and consistent. and don't be affraid to refactor if your team says they are not clear. personally i would go with findCompetition(user, year) with non-primitive types because you can use method overloading but then in invocations you have to use constants or reading enablers like findCompetition(forUserId(userId), forYear(year)) to explicitly tell the reader which version you are invoking.
what is manager? it means nothing. similarly to helper, handler etc. Service contains the logic that converts DTO to entities and the logic can't be pushed to the domain/entity because the logic operates on many entities. as stated before i group components (not only services) by functionality and therefore i add the 'Service' suffix because it helps me quickly find the logic in specific package (which contains model, controller, service, repository etc)
The description may sound like just a bunch of words so here is a more detailed explanation. I have a User object which is mapped to database table.
I want users to be in different roles. There will be a bunch of those - and they technically will be the same users in same table but to them will apply different roles. Say user in role A will have to have two fields as required, and will have to have certain restrictions to the length and contents on his password, as well as the time expiration of his password, etc.
While I can hardcore those rules I am very interested to find out of there is an other way to define the rules and may be store in database so it's easier to load/apply and the main idea - to change and update them -- without redeploying the codebase.
Technically the stupidest and straightforward solution is to implement class, serialized, store in db, then load, deserialze, call methods on it which will execute rules. The problem is in changes to the ruleset ( read "interface" of the rule class ) and that generally solution sounds like a hack.
Anytihing else? Any frameworks? Other approaches?
UPDATE: probably was not clear. say, I have class User.java
I need to define different rules say:
1. do we need to verify length of password, and what should it be?
2. do we need to require some properties to be required?
3. do we need to track login attempts for this user?
4. if we do track, how many login attempts allowed?
5. do we expire password?
6. if we do, then in how many days? or months? or weeks?
7. ...
and so on and so on.
so questions ARE.
- how do I define those rules and operate on User object WITHOUT modifying and redeploying code base?
- how do I store those set of rules?
Drools, jBPM, etc. do not seem like a fit for that task. But any advice would help!
JRuleengine is good I heard, sometime back I planned to use it for similar application.
There are many other Rule Engines though.
Well there are some good rules engines out there include jrules, drools I think is popular too. One thing to keep in mind is the relationship between a rule and the data it examines. After all you can have the rules in a word document, but when they execute they need examine data, and that is also a factor in choosing a rule engine or architecture. generally its if (a > b) then do y. Means you need to examine a and b in the rule execution. That is the real issue is how to get the parameters into the rule and engine.
For an audit log, i need to know the differences between 2 objects.
Those objets may contains others objets, list, set of objects and so the differences needed maybe recursive if desired.
Is there a api using reflection (or other) already for that ?
Thanks in advance.
Regards
It's a pretty daunting problem to try and solve generically. You might consider pairing a Visitor pattern, which allows you to add functionality to a graph of objects, with a Chain of Responsibility pattern, which allows you to break separate the responsibility for executing a task out into multiple objects and then dynamically route requests to the right handler.
If you did this, you would be able to generate simple, specific differentiation logic on a per-type basis without having a single, massive class that handles all of your differentiation tasks. It would also be easy to add handlers to the tree.
The best part is that you can still have a link in your Chain of Responsibility for "flat" objects (objects that are not collections and basically only have propeties), which is where reflection would help you the most anyway. If you "catch-all" case uses simple reflection-based comparison and your "special" cases handle things like lists, dictionaries, and sets, then you will have a flexible, maintainable, inexpensive solution.
For more info:
http://www.netobjectives.com/PatternRepository/index.php?title=TheChainOfResponsibilityPattern
http://www.netobjectives.com/PatternRepository/index.php?title=TheVisitorPattern
I have written a framework that does exactly what you were looking for. It generates a graph from any kind of object, no matter how deeply nested it is and allows you to traverse the changes with visitors. I have already done things like change logs generation, automatic merging and change visualization with it and so far it hasn't let me down.
I guess I'm a few years too late to help in your specific case, but for the sake of completion, here's the link to the project: https://github.com/SQiShER/java-object-diff