In Symfony2, should I use an Entity or a custom Repository - orm

I am creating a new web app and would like some help on design plans.
I have "store" objects, and each one has a number of "message" objects. I want to show a store page that shows this store's messages. Using Doctrine, I have mapped OneToMany using http://symfony.com/doc/current/book/doctrine.html
However, I want to show messages in reverse chronological order. So I added a:
* #ORM\OrderBy({"whenCreated" = "DESC"})
Still I am calling the "store" object, then calling
$store->getMessages();
Now I want to show messages that have been "verified". At this point, I am unsure how to do this using #ORM so I was thinking I need a custom Repository layer.
My question is twofold:
First, can I do this using the Entity #ORM framework?
And second, which is the correct way to wrap this database query?
I know I eventually want the SQL SELECT * FROM message WHERE verified=1 AND store_id=? ORDER BY myTime DESC but how to make this the "Symfony2 way"?

For part 1 of your question... technically I think you could do this, but I don't think you'd be able to do it in an efficient way, or a way that doesn't go against good practices (i.e. injecting the entity manager into your entity).
Your question is an interesting one, because at first glance, I would also think of using $store->getMessages(). But because of your custom criteria, I think you're better off using a custom repository class for Messages. You might then have methods like
$messageRepo->getForStoreOrderedBy($storeId, $orderBy)
and
$messageRepo->getForStoreWhereVerified($storeId).
Now, you could do this from the Store entity with methods like $store->getMessagesWhereVerified() but I think that you would be polluting the store entity, especially if you need more and more of these custom methods. I think by keeping them in a Message repository, you're separating your concerns in a cleaner fashion. Also, with the Message repository, you might save yourself a query by not needing to first fetch your Store object, since you would only need to query to Message table and use its store_id in your WHERE clause.
Hope this helps.

Related

Bulk POST request without enumerating objects

I'm trying to let my API clients make a POST request that bulk modifies objects that the client doesn't have their IDs.
I'm thinking of implementing this design but I don't feel good about it, are there any better solutions than this?
POST url/objects/modify?name=foo
This request will modify all objects with the name foo
This can be a tricky thing to do with an API because it doesn't age very well.
By that I mean that over time, you might introduce more criteria for the data stored on resources (e.g., you can only set this field to "archived" if the create_time field is older than 6 months). When that happens, your bulk updates will start to only work on some resources and now you have to communicate that back to the person calling the API.
For example, for any failures you need to explain that the update worked for some resources (and list them out) but failed on others (and list them out) and the reason why for each failure (and remember you might have different failure conditions for different resources).
If you're set on going down this path, the closest thing I can think of is the "criteria-based delete" method shown here: https://google.aip.dev/165.

API interface design - toggle or 2 different interfaces

I am studying interface design.
Here is what I curious about.
Some of open API support 2 different interfaces to implement toggling. i.e. instagram like interface. It separates like interface(like, cancel like)
What is the advantage of separate those two.(separating into two interfaces makes end-user more complicated in my view)
I question this, since it could be implemented with toggle.
i.e. user send item_id and user_id. server check database(this item is already liked or not), and update.
Thanks for answer!
The real benefit to having two interfaces for toggling is that it doesn't require the user to know the current state of the thing they are attempting to change (i.e. it doesn't require me to first query for the state).
If I am a consumer of an API, typically I will want to perform actions such as like-ing something. Very rarely can I think of a case where I would want to perform the action of do the opposite of what I did previously (unless I'm feeling like flip-flopping). If you didn't have two endpoints for like and unlike then you'd first have to poll the API to get the current status, and then perform the toggle that you're talking about if needed.
This situation introduces more logic into your code, requires that you make 1-2 calls to the API, and assumes that the state didn't change between calls; whereas having two endpoints reduces the logic, limits your API calls to 1 per action, and you don't have to worry about the state changing unexpectedly.
In the case where you try to like something that the user has already liked, then the API would simply return a successful result and not alter the underlying data.
One reason to prefer an interface where you specify the desired state explicitly is that it will be idempotent. That is, the resulting state is the same even if the request is made multiple times.
This is a pretty contrived example, but if two different people sharing the same account tried to like the same thing within a small enough window, you could end up with it being un-liked instead.

CQRS - options around "get or create"

I'm putting something together using a CQRS pattern (no event sourcing, nor DDD, but a clear difference between command and query).
The operation I'm trying to model is a "get-or-create", given a set of parameters. The item being created (or gotten) is effectively a unique communications link ID. Either of two parties can say "get-or-create comms link between me and the other" and a new temporary random ID is returned (which would be valid between them both). They can then send/receive messages using that ID (a PostMessage command or GetRecentMessages query). This temporary ID can be passed around, but can also be centrally invalidated, controlled, etc. Different sessions between the two parties should be recorded separately.
I know that the more typical "insert-then-get-me-the-ID-back" is handled by the command having a GUID parameter. But this doesn't seem to apply here because of course the item might already exist..
My options, I believe:
Execute a GetOrCreateCommsLink command followed by a GetActiveCommsLinkId query, i.e. command, then query. Feels wrong because commands are supposedly typically asynchronous (though not in my simple prototype so far), and is it right to wait for a command then run a query in my service layer?
Run a GetExistingOrNewActiveCommsLinkId query, which will either return an existing session ID, or create and return one. Feels wrong because it's a dirty cheat, both reading and mutating state in a query..
Don't use CQRS for this part of the app
Have each client use their own ID for the session - NotifyCommsLinkIdentifier command from each side specifies the parameters and their own ID, which is linked internally to the actual ID by the command. Then run a GetUnderlyingCommsLinkId query, given the identifier previously specified, to uncover the ID if needed. Feels wrong to because inventing this extra concept seems to be only because of the CQRS pattern, rather than any actual domain/business need
I suppose my question in general is how to deal with potential get-then-act, or act-then-get scenarios. Should I simply chain them together in my service layer, as per option 1.
Is there a standard approach, or standard approaches, to this?
So you are talking about CQS, not CQRS. Basically you are trying to find workarounds in order to strictly implement CQS pattern for something that naturally may not really be an asynchronous command.
My advice is: don't try to apply a pattern because of the pattern, but because it makes sense. Does it make sense in your case? What would be the benefit? Remember that you are not Amazon. Do you really need it?
That said, what I typically do is not the purist way, but allowing a command to return a simple ID if it's needed. This will make your architecture a lot more simple; and you still separate commands from queries which to me is the most important advantage.

Using Documentum DQL to get contents of all users' worklows

I know almost nothing about Documentum, so there are probably omissions in the information you need to answer my questions. But I'm going to try, anyway...
We use Documentum (obviously). Within Documentum, users can create workflows. These workflows contain ordered lists of services that are used to process data. So, we may have ServiceA, ServiceB, ServiceC, ServiceD, and ServiceE, and a user can create a workflow that says to process the data using, in order: ServiceC, ServiceA, and ServiceB. Another user's list might be: ServiceA, ServiceD, ServiceE.
I've been asked to find a way to get a list containing the id/name of each user, the user's workflow id (name?), and items within the workflow. From what I've read here on StackOverflow and elsewhere, it looks like this is possible via DQL.
And, if I have the DQL, it turns out that this will be simple to do using interfaces we've already built. If it's too complex, I'll need to write Java and use the API. I'd prefer the DQL.. :-)
So, can someone here provide me with a pointer to a reference on DQL, and perhaps some pointers on what to look at/for?
Maybe you need more than one DQL-Query. However, I would strongly recommend writing some DFC code and iterating over the results.
I would suggest to have a look in the Documentum Content Server Object Reference to find out more about the attributes of type dm_workflow (and, of course, related types like dmi_workitem, dmc_workqueue, etc.).
These types should provide the information you are looking for and where you might start best.

Why is my Navigation Properties empty in Entity Framework 4?

The code:
public ChatMessage[] GetAllMessages(int chatRoomId)
{
using (ChatModelContainer context = new ChatModelContainer(CS))
{
//var temp = context.ChatMessages.ToArray();
ChatRoom cr = context.ChatRooms.FirstOrDefault(c => c.Id == chatRoomId);
if (cr == null) return null;
return cr.ChatMessages.ToArray();
}
}
The problem:
The method (part of WCF-service) returns an empty array. If I uncomment the commented line it starts working as expected. I have tried turning of lazy loading but it didnt help.
Also, when it works, I get ChatMessages with a reference to ChatRoom populated but not the ChatParticipant. They are both referenced by the ChatMessage-entity in the schema with both Id and Navigation Properties. The Ids are set and points to the right entities but on the client-side only the ChatRoom-reference has been populated.
Related questions:
Is an array the preferred method to return collections of EF-entities like this?
When making a change in my model (edmx) Im required to run the "Generate Database from Model..."-option before I can run context.CreateDatabase(). Why? I get some error message pointing to old SSDL but I cant find where the SSDL is stored. Is this created when I run this "Generate Database..."-option?
Is it safe to return entire entity-graphs to the client? Ive read some about "circular reference exeptions" but is this fixed in EF4?
How and when is references populated in EF4? If I have lazy-loading turned on I suspect only entities I touch is populated? But with lazy loading turned off, should the entire graph be populated always then?
Are there any drawbacks of using self-updating entities over ordinary entities in EF4? I dont need self-updating right now but I might do later. Can I upgrade easily or should I start with self-updating from the start?
Why cant I use entity-keys with type string?
Each of your questions needs a separate answer, but I'll try to answer them as briefly as possible.
First of all, in the code sample you provided, you get a ChatRoom object and then try to access a related object that is not included in your query (ChatMessages). If lazy loading is turned off as you had suggested, then you will need the Include("ChatMessages") call in your query, so your LINQ query should look like this:
ChatRoom cr = context.ChatRooms.Include("ChatMessages").FirstOrDefault(c => c.Id == chatRoomId);
Please ensure that your connection string is in your config file as well.
For the related questions:
You can return collections in any way you choose - I have typically done them in a List object (and I think that's the common way), but you could use arrays if you want. To return as a list, use the .ToList() method call on your query.
I don't understand what you're trying to do here, are you using code to create your database from your EDMX file or something? I've typically used a database-first approach, so I create my tables etc then update my EDMX from the database. Even if you generate your DB from your model, you shouldn't have to run CreateDatabase in code, you should be able to run the generated script against your DB. If you are using code-only then you need to dump the EDMX file.
You can generally return entity graphs to the client, should handle ok.
EF4 should only populate what you need. If you use lazy loading, it will automatically load things that you do not include in your LINQ query when you reference them and execute the query (e.g. do a ToList() operation). This won't work so well if your client is across a physical boundary (eg a service boundary) obviously :) If you don't use lazy loading, it will load what you tell it to in your query and that is all.
Self tracking entities are used for n-tier apps, where objects have to be passed across physical boundaries (eg services). They come with an overhead of generated code for each object to keep track of its changes, they also generate POCO objects which are not dependent on EF4 (but obviously contain generated code that would make the tracked changes work with the EF4 tracker). I'd say it depends on your usage, if you're building a small app that's quite self contained, and don't really care about separation for testability without the infrastructure in place, then you don't need to use self tracking entities. I say only use framework features when you need them, so if you're not writing an enterprise scale application (enterprise doesn't have to be big, but something scalable, highly testable, high quality etc) then no need to go for self tracking POCOs.
I haven't tried but you should be able to do that - that would be a candidate for a separate question if you can't get it to work :)