I am trying to add user and friend services using lagom framework. I read lagom persistent doc but still not able to understand how should I decide on entity id? Since it should be unique to retrieve it back. The random uuid generated is one option but that would be unusable since while sending command those uuid will not be available to other user/services.
Here are two solutions I can think of:
1) use email as entity id.
2) push the uuid and user name/id in database so that service retrieve uuid and then send command.
As per my understanding Solution 2 is two step process and defeats the purpose.
Solution 1, for other services like friend service there might be cases which can be duplicated or needs to send more information to retrieve the entity id.
Also I couldn’t find a better way to implement dean on services in this framework. Is there a way to do that?
There are no simple answers to your question, because it all depends on how the interaction between the services will look. But you should think about Entity Id as a unique identifier which also doesn't change in time. Changing Entity Id means creating new entity. In my opinion, email is not a good candidate for an Entity Id, because user may change it and also use more than one. I would go for UUID and would keep track on emails, plus expose methods which can handle communication between the services using for example user email (one of his emails), phone number(s), 3rd party service Ids, etc.
Related
Assuming a resource X(http://example.com/a/foo/7) from rest-service A needs to hold a reference to a second resource Y(http://example.com/b/bar/1) from rest-service B.
How would one persist the reference?
Currently I'm storing the whole URI (as a string) of Y in the persistence layer of service A. Is this a common/valid approach?
It seems wrong to me to extract the id(1) out of Y's URI as I would implement assumptions about the URI structure of service B in service A. Is this correct?
How do you solve this problem?
Thx!
Lets discuss it with some actual business domain , then the answers will make sense.
So first example:
X represents Order Entity in Amazon Order Service, Y represent Customer in Customer Service.
Now while fetching the order from Amazon from Order Service, you also want to show some basic customer detail and link to customer Object to go to Customer Detail Page.
In this case what I would do is while creating the order copy some basic attributes of the customer in Order Entity (customerName , customerArea).
Also store customerId, customerType. And as the API for fetching customer is Public and also exposed to various internal services, Order Service will do a Service discovery and create URL and call. In these cases generally customer service will not stop supporting the old way (even if they are building a new one).
So storing just the id is a solution.
CASE 2:
Amazon Order Entity wants to store delivery details and delivery partner is some third party entity like DHL , then if DHL provides a URL to fetch the delivery updates to the order, in those cases I will just store the URL.
Generally I will prefer to store id and service type and some basic details to create a good customer experience and also avoid hitting one extra service api for getting the basic detail like customer name.
Storing direct URL makes sense when its a third party URL.
Also if you can give certain example of your business case like this, we can discuss better
IMO references should be stored as is. How you get the actual data from reference should not be part of the data but the logic which may change from time to time.
I will store them as reference of external reference (just to paint the picture that reference is out side our service) and coupled it with a logic to query the data.
URL is very volatile and may change. As a rule of thumb you should never keep urls in you database and should rely on service discovery to identify where the service is even if its within you own infra.
Its not an assumption, its a contract, which may changes and if it does, your service will be dependent service and has to make due changes
Also by your logic, even if you keep url, response to it is still a contract that both of you adhere to.
Let's assume I have a project similar to the google sample code:
https://github.com/googlesamples/android-architecture-components
I want to add an account system to the app. How can I persist data and make the following scenario work:
go to persistent-data-fragment and load data from backend
log out
log into a different account
go to that same fragment
As a result, I should not be able to see the first user's data and instead load them from backend for the second user. How to use Room for that?
It a generic question, so I can answer with a generic answer :).
1 - on the server side you need to authenticate a user that access to REST services. There are many ways to do this. JWT is a good solution. Start reading this article.
2 - on the client side, probably you need to introduce in your database a user table and link other database's entities to user identity. Using Room you have to declare a user bean and then link them to other room entities.
I hope it helps.
I'm refactoring a application to DDD, and so far so good but i got a doubt about some responsibility and what are the best approaches to solve it.
The application is a web app that call center agents use, with CRM features, the backend is a REST API.
The use case is as follows: The agent calls to a customer and need to collect some information / offer promotions etc.
After calling the customer and talked to him, he needs to fill some information for this contact attempt, some of that information is combo box with data filled from the database, and it sends a POST with the IDs of the entities to a endpoint to register it.
So we have a endpoint contactAttempt that receive the data, customerId, agentId, some combo box info (subjectId, reasonId, extraInfo1, extraInfo2), the extra info doesn't call that, but just to simplify.
That information is deserialized to a DTO object that is passed to a application service, which consult the respective repository to check if the ids are valid and return the Entities, if the entities are not found, it throws a exception that the controller catches and answer the client with a message.
If all the entities are valid, there are some domain rules, like if is the first contact with the customer, sends a welcome e-mail, and other stuff.
My doubt is with this steps of fetching entities from the Repository, it should be like that or should i fetch it in the controller, and if all that i need is present, then i pass to the domain service with just the logic needed to apply the business rules?
What are the pros and cons of the mentioned approaches?
Is there other approaches?
In the context of a MVC, what is the responsibility of the Controller?
The MVC is responsible to deserialize the HTTP request in a message for the "application layer".
So it should get from the querystring/body/headers all the values needed and pass to a service as immutable values (command). This because the application service (handler, whatever) should execute the command transactionally, and if the entities (so, the behavior) are accessed outside the application layer, you can't assure that no modification happens outside the application layer.
I'm getting familiar with Breeze because I think that it can help me a lot dealing with data. Hovewer my biggest concern is data validation on server side. I read the documentation and I know that you should use your own ContextProvider and apply custom validation inside. I also read this SO post where someone was asking similar question.
But I think I got the case that cannot be handled in BeforeSaveEntity function. If it can, please tell me how:
Let's say that user is trying to update an article (his own article). This article has some ID.
How could I check if user is updating his article and not someone elses (he could change article ID in the browser, and this ID could be someone elses article ID). So entity would be still valid, but business rule does not allow to change other users articles by everyone.
I want to use EntityFramework and ASP.NET Web Api by the way.
If only i could get to something like "current user" and ID of article inside BeforeSaveEntity function...
You are rightly concerned to validate client save requests thoroughly and right also to distrust-in-principle anything the client sends.
Two issues here: who is the user and does s/he really own this article.
Who is the user?
Breeze stays out of the authentication business which we believe should be addressed by means that are (largely) external to the application code you write on server and client.
I would not roll my own security layer. That's asking for trouble. You might start your research with this article by Mike Wasson on Web API security.
Once you know who the user is, you must get application-specific facts about him or her such as the userId and what the user is allowed to do. I don't know where you get those facts as that is something specific to your application.
Whose article is this?
Let's suppose the current userId is 12345 and the update request specifies an article with articleId == 42 and userId == 12345. Clearly this article belongs to the current user. Is that good enough? Should we go ahead and save the changed article?
The answer depends upon how you assess the consequences of a rogue client updating another person's article. I'm not worried about updating a Todo (maybe I should?). I wouldn't trust this request if it concerned a bank withdraw.
I recommend spinning up a separate DbContext and querying the database for articleId 42.
Do not query the database with the DbContext from the Breeze ContextProvider inside the BeforeSave. That DbContext holds the modified article from the client. You want a separate DbContext to hold the actual entity per the database as it stands right now. These are separate entity objects in separate states. You can't have two different articles with the same id in the same DbContext.
If the queried article has userId 12345, you know the client made a valid request and you proceed. If the queried article's userId property is other than 12345, you reject the request.
You might treat this failed request as a potential attack and log it where you log security attacks. Maybe you'll monitor this user and the IP address and who knows what. I'm out of my depth here.
I'd probably reject the request with a mysterious 500. A real client wouldn't have made such a request and I don't want to tell a potential attacker the reason I rejected it.
I'm building a API Centric web application but I'm having trouble wrapping my head around some of the business logic.
Take this Use Case:
POST /companies -> User adds a new Company which has a Location
(Company Entity has a Location Entity which keeps the address of the company, A Company has one Location, a location can have multiple Companies)
PATCH/PUT /companies/{id} -> User edits a Company information (changes street name from Company->Location
I want my API to be able to check if there are already other companies on that Location.
If this is the case, I want the user the chose between editing the Location Entity (which will change then for all Companies on that Location) or create a new Location.
How do I send this choice back to the User in a RESTful manner?
easy :
PUT replace the entire resource if it exists or create a new resource if it doesnt exist. there is no choice to be made if you want to stay strictly REST( but you dont have to) .it's up to your users to check if the company exists with a GET before a put.
POST is suppose to replaced all the companies collection.
You could use PATCH however to update an existing company.
see : https://www.rfc-editor.org/rfc/rfc5789
The REST API or any strict service would provide a response based on a request. So the REST API can definitely respond back to the user if other companies are related to the location. But there is no way for the API to respond back with a choice. The API can respond back with some information and the user will need to make another request based on that information.
Instead, it is better to give the user the option to specify it upfront. So, the choice of whether related companies should be updated for the location is made upfront by the user as par of the request. For example, the user can specify this as a query param on the REST API and the service can take appropriate action based on that query param.