RxJava multiple http requests and combine the result into a single object - http

I would like to find a way to implement the following using RxJava:
For instance, let's suppose we have a userId, that allows us to get information from three different microservices:
Now the friends might be multiple, as well as the purchases, so the emission would probably look something like this:
The end result of the process should be an object that looks like this:
public class Profile{
User user;
List<Friend> friends;
List<Purchase> purchases;
}
Is there a way to do this in RxJava, combine the results from more that 2 HTTP calls even if there are multiple emissions associated with some of the calls we want to combine?

Related

DDD : How to model association between aggregate roots

We have a aggregate root as follows.
#AggregateRoot
class Document {
DocumentId id;
}
The problem statement given by the client is "A document can have multiple document as attachments"
So refactoring the model will lead to
//Design One
#AggregateRoot
class Document {
DocumentId id;
//Since Document is an aggregate root it is referenced by its id only
Set<DocumentId> attachments;
attach(Document doc);
detach(Document doc);
}
But this model alone won't be sufficient as the client wants to store some meta information about the attachment, like who attached it and when it was attached. This will lead to creation of another class.
class Attachment {
DocumentId mainDocument;
DocumentId attachedDocument;
Date attachedOn;
UserId attachedBy;
//no operation
}
and we could again refactor the Document model as below
//Design Two
#AggregateRoot
class Document {
DocumentId id;
Set<Attachment> attachments;
attach(Document doc);
detach(Document doc);
}
The different possibilities of modeling that I could think of are given below.
If I go with design one then I could model Attachment class as an aggregate root and use Events to create them whenever a Document is attached. But it doesn't look like an aggregate root.
If I choose design two then Attachment class could be modeled as a value object or an entity.
Or If I use CQRS, I could go with design one and model Attachment as a query model and populate it using Events.
So, which is the right way to model this scenario? Is there any other way to model other what I have mentioned?
You might find in the long term that passing values, rather than entities, makes your code easier to manage. If attach/detach don't care about the entire document, then just pass in the bits they do care about (aka Interface Segregation Principle).
attach(DocumentId);
detach(DocumentId);
this model alone won't be sufficient as the client wants to store some meta information about the attachment, like who attached it and when it was attached.
Yes, that makes a lot of sense.
which is the right way to model this scenario?
Not enough information provided (the polite way of saying "it depends".)
Aggregate boundaries are usually discovered by looking at behaviors, rather than at structures or relationships. Is the attachment relationship just an immutable value that you can add/remove, or is it an entity with an internal state that changes over time? If you change an attachment, what other information do you need, and so on.

How to make a controller accept post data from the body as well as URL in MVC 6 ASP.NET 5

Currently I am trying to write a controller in MVC 6 that is capable of accepting data from a post request. The issue is that depending on the client (which is not always a web browser), the data can come in as either key value pairs in the request URL, or as JSON in the request body.
Currently this method works for accepting the data from the URL:
[HttpPost]
public async Task<CaptureResponse> CaptureData(CaptureInfo capture) {
...
}
After a lot of trial and error (and stack overflow answers), I figured out that the [FromBody] attribute tells the model binder to look in the request body, which is required now because MVC 6 combines WebApi and standard MVC together. The following code parses data from JSON in the form body:
[HttpPost]
public async Task<CaptureResponse> CaptureData([FromBody] CaptureInfo capture) {
...
}
For simplicity, I would like to combine the two together somehow, so the model binder gives me the data in the same parameter variable. So far, the only way I can get the data into the same Action is to specify two parameters, one for the URL and one for the body, and do some null checking on each like so:
[HttpPost]
public async Task<CaptureResponse> CaptureData(CaptureInfo capture, [FromBody] CaptureInfo bodyCapture) {
if (bodyCapture != null) {
if (bodyCapture.RequiredProperty1!= null
&& bodyCapture.RequiredProperty2!= null) {
capture = bodyCapture;
}
}
...
}
I have tried specifying multiple properties before the input attribute like this:
[HttpPost]
public async Task<CaptureResponse> CaptureData(CaptureInfo [FromQuery][FromRoute][FromForm][FromBody] capture) {
...
}
But it does not work. Any ideas if something like this is possible?
As far as I know, it is just not possible. Of course you can try using workarounds, basically doing all request parsing yourself. It doesn't sound good, does it?
If you really want the things your way, I believe the best approach is to have two distinct endpoints in the controller and the private method for actual processing. Or, perhaps, even extract that method into an additional abstraction layer with BlaBlaService (CaptureService in your case, probably) class(es) responsible for all the dirty work. Sometimes it makes sense to separate your controllers layer from business logic - for example, for testing purposes.
PS: Your idea is quite similar to what was the approach in good old .NET & PHP times, and believe me, this particular idea is not the one that made those times good. You know, the MVC is much about the REST-like approach, so each endpoint of your controller is supposed to be dedicated to its own single function and obey to a single and uniform "intuitive" protocol.
The "intuitive" way to submit data to POST request for developers acquainted with REST is through the request body. I suggest you to consider going with this approach as the only one.
You need use Request.Form
like:
string username = HttpContext.Current.Request.Form.GetValues("key1")[0].ToString();
string password = HttpContext.Current.Request.Form.GetValues("key2")[0].ToString();
string something = HttpContext.Current.Request.Form.GetValues("key3")[0].ToString();

How to get an item in a collection with extra attributes

I currently get an item in a collection for a user like so:
me.user = Backbone.Collection.Users.collection().get(id);
This returns the default set of attribute required in the app. On the user profile page, I want to show additional attributes that aren't necessary anywhere else.
How can I get an item in a collection (which queries the server) with additional attributes that I can specify?
Thanks
So to go along with the comment, what I think you want is to produce extra models instead of creating two user models, one with redundant + extra data.
One way you could do this is to give a relationship between different models.
Say a user model consists of simply a name and email. That's fine and dandy but you also want to render a user profile on the page (or whatever 'extras' you intend.) This seems like a good opportunity to create a separate model representing the extra data you desire.
You can do it a few ways. For example, if every user has a profile you could bake it into your user model. Something like when you create a user model:
user.profile = new Profile(); // model
I've seen some people put other models inside a model's attributes user.set('profile', new Profile()) but I'm not sure if this is a great idea. I like to keep my model attributes isolated to just that model.
Each profile model would have a url that corresponds to the model.id.
So then you could just user.profile.fetch() and use that profile attributes to populate the data in your view. Maybe it does something like /user/1/profile
Another aspect about your question that I think you might be alluding to is sending data from the server in one go when you fetch the collection. Maybe your server replies with data like this:
[{"name":"Jake", "email":"j#stack.com", "profile":"{"aboutme":"Some story"}"}, ... ]
and the profile data is only available for those who have it etc. In this case, you can then use the parse() function to pull out that extra data out and doing something before sending the name and email attributes through to the model set method.
Although, recently I think I read that using the parse to do stuff with the extra data is bad form. Override set So instead of parsing, you might just want to save that for namespacing and then in your overridden set method do something like:
set: function(attributes, options) {
if (!_.isUndefined(this.profile) && attributes.profile) {
this.profile = new Profile();
this.profile.set(attributes.profile);
} else if (attributes.profile) {
this.profile.set(attributes.profile);
}
delete attributes.profile;
return Backbone.Model.prototype.set.call(this, attributes, options);
}
You can do something similar for really unique users such as the main user using your app. When I instantiate a user model for my app (the one representing user him/herself) I also initialize a few other special models only that user would have (like an auth model for fetching authentication data etc.)
I'm not sure if I hit what you were asking but I hope I hit something.
Is collection an instance already, and I assume so? If so, you should only do:
me.user = Backbone.Collection.Users.collection.get(id);
I.e. removing the brackets () after collection.

How can I load a vertex with related vertex as a collection

GraphDb side
Vertex:User
Edge:Has
Vertex:Car
Object Side
public class User {
public string Name { get; set; }
[GraphEdge("HAS_CAR")]
public ICollection<Car> Cars { get; set; }
}
Problem
I want to get User X with Cars property from Neo4J via Gremlin? (I'm using Neo4jClient)
It's so similar Include method of Linq to Entity..
Best regards
Assuming a graph like this:
You would use a Gremlin query like this to retrieve all of the cars, for all users:
g.v(0).out('HAS_USER').out('HAS_CAR')
Now, lets filter it down to just the red cars:
g.v(0).out('HAS_USER').out('HAS_CAR').filter { it.Color == "Red" }
Finally, you want the users instead of the cars. It's easiest to think of Gremlin working like an actual gremlin (little creature). You've told him to run to the users, then down to each of the cars, then to check the color of each car. Now you need him to go back to the users that he came from. To do this, we put a mark in the query like so:
g.v(0).out('HAS_USER').as('user').out('HAS_CAR').filter { it.Color == "Red" }.back('user')
To write this in C# with Neo4jClient is then very similar:
graphClient
.RootNode
.Out<User>(HasUser.TypeKey)
.As("user")
.Out<Car>(HasCar.TypeKey, c => c.Color == "Red")
.BackV<User>("user")
The only difference here is that you need to use BackE or BackV for edges and vertexes respectively intead of just Back. This is because in the staticaly typed world of C# we need to use different method names to be able to return different enumerator types.
I hope that helps! :)
--
Tatham
Oğuz,
Now that you have updated the question, I understand it better.
GraphEdgeAttribute is not part of Neo4jClient, so I'm not sure where it has come from.
In Neo4jClient, we do not load deep objects. That is, we will not follow properties and load further collections. We do this because a) it would require us to do lots of roundtrips to the server and b) we think you should be explicit about what data you actually want to load. We do not want to be an equivalent to the Spring Data for Neo4j project because I do not believe it is a good approach.
It sounds like you might want to look at Cypher instead of Gremlin. That will let you load data as tables, including projections from multiple nodes.
-- Tatham

asp.net MVC: Pass query string as a string, or individual parameters?

In asp.net MVC I have a search action in my controller and I am trying to decide If I should pass the query to my repository as a string
public ActionResult Search(string query)
{
return View(_repository.ListPeople(query));
}
or as individual parameters:
public ActionResult Search(string FirstName, string LastName, System.Nullable<byte> Education)
{
return View(_repository.ListPeople(FirstName, LastName, Education));
}
A lot of examples I have seen online use the query string method, but to me it doesn't feel as "safe", even though it's a little easier to deal with when you have a bunch of parameters to pass in. Is there a general consensus as to the better way to do this?
I would favour model binding. That way if you decide to add extra search options you have no changes to make apart from the model class.
Info here and here
Personally, I prefer to not have the repository take on the responsibility of parsing a query string. Looking at it from a separation of concerns point of view, I feel that the repository should remain implementation-agnostic. Having to create query strings for unit testing, for example, is more cumbersome than calling the method directly with parameters.
That being said, I also prefer to have controllers interface with well-defined services, as well, as it helps to keep the controllers lighter, in my experience. I try to let the service act as a gateway to the repository, although there is no requirement to do so. There are two things that I will pass into a repository (or more likely, service), depending upon what the purpose of the call is - either a set of parameters, like you give in your second example, or as a constructed domain object, if applicable.
I would most definitely suggest going with the second route. There's no need to couple your controller with your repository. Let your repository be in charge of getting data, it shouldn't have to do any kind of parsing of a query string. That's not its job. Let the controller deal with that.

Resources