Rehydrate store references in Mobx - mobx

What is the best way to rehydrate your store during app initialization, specifically the references between stores?
For instance, lets say I have 2 api calls:
/todos -> return array of todos
[{id: 1, person_id: 2}]
/persons -> return array of Persons
[{id: 2, name: 'John'}, {id: 3, name: 'Sam'}]
and a Todo object looks like this
class Todo {
...
#observable person;
...
}
Some of the Todos will have a reference to a Person, but not all of them, and not all of the Persons will be referenced, so its not as simple as just scrapping the Persons api call and just returning the Person reference with the Todos api call.
However, we can't be sure that the Persons api call will be returned first, so we cannot just assume to link up the Todo / Person reference whenever the todos response arrives (would like to run calls in parallel)...
Is it just a matter of extra logic in the client side code to ensure we set up all references whenever the data comes in? Or is there some better practice anyone has found in there experience.
EDIT
The more I think about it, I'm thinking the most predictable logic would be to always either get or create a reference object.
So in the above example, if the Todos response comes in first, we would look for the Person object with the id of 2, if it exists great, if it doesn't, create it and reference that object. Then when the persons response comes in it would do the same thing...look for Person with the id of 2, if it exists, update it with the new data, if not, create it.
Anyone have any better ideas?

The simplest way is indeed to load your objects in order, and find them. After that to load them in parallel, and find-or-create placeholders if you refer to them. It's quite a common pattern.

Related

Mobx-state-tree create form with types.identifier field on model

I've started using mobx-state-tree recently and I have a practical question.
I have a model that has a types.identifier field, this is the database id of the resource and when I query for existing stuff it gets populated.
When I am creating a new instance, though, following the example that Michel has on egghead, I need to pass an initial id to my MyModel.create() on initial state, however, this ID will only be known once I post the creation to the API and get the resulting created resource.
I have searched around for a simple crud example using mobx-state-tree but couldn't find one (suggestions?).
What is the best practice here? Should I do a `MyModel.create({ id: 'foobar' }) and weed it out when I post to the API (and update the instance once I get the response from the API)?
This is a limitation of mobx-state-tree's current design. Identifiers are immutable.
One strategy I've seen to get around this issue is to store your persistence layer's id in a separate field from your types.identifier field. You would then use a library like uuid to generate the types.identifier value:
import { v4 } from "node-uuid"
const Box = types
.model("Box", {
id: types.identifier,
name: "hal",
x: 0,
y: 0
})
const box = Box.create({ 'hal', 10, 10, id: v4() })

Should the response body of GET all parent resource return a list of child resource?

Please bear with me if the title is a bit confusing, I will try my best to explain my question below.
Say I have the following two endpoints
api/companies (returns a list of all companies like below)
[{name: "company1", id: 1}, {name: "company2", id: 2}]
api/companies/{companyeId}/employees (returns a list of all employees for a specific company like below)
[{name: "employee1", id: 1}, {name: "employee2", id: 2}]
What the client side needs is a list of companies, each one of which has a list of employees. The result should looks like this:
[
{
name: "company1",
id: 1,
employees: [ {name: "employee1", id: 1}, {name: "employee2", id: 2} ]
},
{
name: "company2",
id: 2,
employees: [ {name: "employee3", id: 3}, {name: "employee4", id: 4} ]
},
]
There are two ways I can think of to do this:
Get a list of company first and loop through the company list to
make a api call for each company to get its list of employees. (I'm wondering if this is a better way of design because of HATEOAS principle if I understand correctly? Because the smallest unit of resource of api/companies is company but not employees so client is expected to discover companies as the available resource but not employees.)
a REST client should then be able to use server-provided links dynamically to discover all the available actions and resources it needs
Return a list of employees inside each company object and then return a list of companies through api/companies. Maybe add a query parameter to this endpoint called responseHasEmployees which is a boolean default to be false, so when user make a GET through api/companies?responseHasEmployees=true, the response body will have a list of employees inside each company object.
So my question is, which way is a better way to achieve the client side's goal? (Not necessarily has to be the above two.)
Extra info that might be helpful: companies and employees are stored in different tables, and employees table has a company_fk column.
Start by asking yourself a couple of questions:
Is this a common scenario?
Is it logical to request data in this way?
If so, it might make sense to make data available in this way.
Next, do you already have api calls that pass variables implemented?
Based on your HATEOAS principle, you probably shouldn't. Clients shouldn't need to know, or understand, variable values in your url.
If not, stay away from it. Make it as clean to the client side as possible. You could make a third distinct api "api/companiesWithEmployees" This fits your HATEOAS principle, the client doesn't need to know anything about parameters or other workings of the api, only that they will get "Companies with Employees".
Also, the cost is minimal; an additional method in the code base. It's simpler for the client side at a low cost.
Next think about some of the developmental consequences:
Are you opening the door to more specific api requests?
Are you able to maintain a hard line on data you want accessible through the api?
Are you able to maintain your HATEOAS principle in that the clients know everything they need to know based on the api url?
Next incorporate scenarios like this into future api design:
Can you preemptively make similar api calls available? ie (Customers and Orders, would you simply make a single api call available that gets the two related to each other?)
Ultimately, my answer to your question would be to go ahead and make this a new api call. The overhead for setting up, testing, and maintaining this particular change seem extremely small, and the likelihood of data being requested in this way appears high.
I assume that the client you build is going to have an interface to view a list of companies where there will be an option to view employees of the company. So it is best to do it by pull on demand and not load the whole data at once.
If you can consider a property of your resource as a sub-resource, do not add the whole sub-resource data into the main resource API. You may include a referral link which can be used by the client to fetch the sub-resource data.
Here, in your case,
Main-Resource - Companies
Sub-Resource - Employees
Company name, contact number, address - These are properties of the company object and not the sub-resource of a company, whereas, employees can be very well considered as sub-resource.

Is this RESTfull?

I'm a little confused as to what the collection URI's should return.
Say I have a collection, /users of decently large elements. Then we have the expected:
GET /users/123 // returns user element with identifier 123
But what should
GET /users
return? If the collection is large, and the elements are large, it's probably not a good thing to return all elements. Perhaps instead, GET requests at the /users level should return element summaries (identifiers and possibly a few properties), while GET requests at the /users/ level should return actual elements. Then you could do something like;
GET /users
> [{name: abc, id: 1}, {name: def, id: 2}, {name: ghi, id: 3}, ...]
GET /users/2
> {name: def, prop1: *, prop2: *, ...}
Which could be a good way to lazily load data if you wanted to preview important application-domain properties before requesting them in their entirety. With this, in order to apply queries, you'd do something like
GET /users?prop1=value // returns element summaries of elements with prop1=value
GET /users/?prop1=value // returns elements with prop1 = value
Is this approach OK? Or do the other methods acting on /users then loose meaning.. (ex. PUT /users ?)
I personally like the style where /users does not return all users but returns information needed to then query specific users. So the summaries approach is how I would generally write it.
If you were filtering or querying, I would go with the first one you provided:
GET /users?prop1=value
I don't care for the second one
GET /users/?prop1=value
because it can be easily misunderstood or lead to confusing and unintended bugs (missing one slash still works but completely changes the results).
You might want to go with an approach of an alternative URL for returning specific users based on search parameters such as
GET /users?prop1=value // returns element summaries based on results of prop1 matching
GET /users/find?prop1=value // returns elements with prop1 = value
Obviously your wording could change (find/search) or you could use a completely different URI but I try to avoid things where two different meanings are a single character/symbol apart to avoid unintended mistakes. Another option would be to make sure you outline this clearly in provided documentation so anyone consuming your API is alerted about this potential.
Actually expanding on this I would go with the all construct.
So instead of using find/search I would provide:
GET /users // returns summaries
GET /users/# // returns element
GET /users/all // returns all elements
GET /users/all?prop1=value // returns all elements that match the filter

REST API Design for Updating Object Graph

I'm designing a REST API and am looking for the recommended best practice for updating object graphs. My question is best explained in an example, so let's say that I have a GET resource as follows:
URI: /people/123
This URI returns an object graph like this:
{
"name":"Johnny",
"country":{"id":100,"name":"Canada"},
"likes":[
{"id":5,"name":"Fruit"},
{"id":100,"name":"Sports"}
]
}
When allowing the API consumer to update this resource, how would you expect the object to be updated via PUT or PATCH? Updating the "name" property is pretty straightforward, but I'm not certain about "country" or "likes", as the consumer can only only change the relationship to other objects and not create new ones.
Here is one way to request the update:
{
"name":"Bob",
"countryId":200
"likeIds":[3,10,22]
}
This update will change the resource to the following:
{
"name":"Bob",
"country":{"id":200,"name":"United States of America"},
"likes":[
{"id":3,"name":"Cars"},
{"id":10,"name":"Planes"},
{"id":22,"name":"Real Estate"}
]
}
This design explicitly and clearly asks the consumer to only update the "IDs" of the "Person", but I'm concerned that the object graph for a PUT/PATCH looks different than the GET, making the API hard to learn and remember. So another option is to request the PUT/PATCH as follows:
{
"name":"Bob",
"country":{"id":100},
"likes":[
{"id":3},
{"id":10},
{"id":22}
]
}
This will yield the same change as the previous update and does not alter the object graph. However, it doesn't make it clear to the API consumer that only the "IDs" can be updated.
In this scenario, which approach is recommended?
In my opinion you should stay with the same structure for both, GET and PUT requests. Why? Because it's quite common to map JSON/XML data into objects, and most (if not all) software that do the actual mapping work best if JSON schema is always the same.
So your webservice should accept a following JSON code:
{
"name":"Joe",
"country":{"id":200,"name":"United States of America"},
"likes":[
{"id":5,"name":"Fruit"}
]
}
However it doesn't have to take into account the country name and may focus only on the country id.

Arbitrarily nesting some attributes in rabl

I'm designing a new API for my project, and I want to return objects that have nested children as json. For that purpose i've decided to use RABL.
I want the client side to be able to understand whether the object is valid, and if not which fields are missing in order to save it correctly.
The design I thought of should include some fields as optional, under an optional hash, and the rest are required. The required fields should appear right under the root of the json.
So the output I try to describe should look something like this:
{
"name": "John",
"last_name": "Doe",
"optional": {
"address": "Beverly Hills 90210",
"phones":[{"number":"123456","name":"work"}, {"number":"654321","name":"mobile"}]
}
}
The above output example describes the required fields name and last name, and the not required address and phones (which is associated in a belongs_to-has_many relationship to the object). name, last_name and address are User's DB fields.
Playing with RABL I didn't manage so far to create this kind of structure.
Any suggestions? I'm looking for a DRY way to implement this for all my models.
RABL is really good in creating JSON structures on the fly, so I don't see why you couldn't achieve your goal. Did you try testing if a field is set to null-able in the schema, and thus presenting it as optional? It seems a good approach for me. For the nested children, just do the same, but extend the template for the children.
For example, in your father/show.rabl display a custom node :optional with all the properties that can be null.
Then, create a child/show.rabl with the same logic. Finally, go back to father/show.rabl and add a child node, extending the child/show.rabl template. This way you could achieve unlimited levels of "optionals".
Hope it helped you.
In this case I'd use the free form option.
From https://github.com/nesquena/rabl
There can also be odd cases where the root-level of the response
doesn't map directly to any object.
In those cases, object can be assigned to 'false'
and nodes can be constructed free-form.
object false
node(:some_count) { |m| #user.posts.count }
child(#user) { attribute :name }