Which relay objects must implement `Node`? - relayjs

https://facebook.github.io/relay/graphql/objectidentification.htm is very clear around what Node is and how it behaves, but it doesn't specify which objects must implement it, or what the consequences are if your object doesn't implement it. Is there a set of features that don't work? Are such objects completely ignored? Not all objects in the existing spec (e.g. pageInfo) implement it, so it's clearly not universally required, but pageInfo is somewhat of a special case.

Another way of thinking about the Node interface is that objects that implement it are refetchable. Refetchability effectively means that an object has an ID that I can use to identify the object and retrieve it; by convention, these IDs will usually be opaque, but will contain type information and an identifier within that type (eg. a Base-64 encoding of a string like "Account:1234").
Relay will leverage refetchability in two ways:
Under a process known as "diffing", if you already have some data for an object identified by ID QWNjb3VudDoxMjM0 (say, the name and address fields), and you then navigate to a view where we show some additional fields (location, createdAt) then Relay can make a minimal query that "refetches" the node but only requests the missing fields.
Relatedly, Relay will diff connections and will make use of the Node interface to fill in missing data on those (example: through some combination of navigation you might have full information for some items in a view, but need to fill in location for some items within the range, or you might modify an item in a connection via a mutation). So, in basic pagination, Relay will often end up making a first + after query to extend a connection, but if you inspect its network traffic in a real app you will also see that it makes node queries for items within connections.
So yes, you're right that pageInfo doesn't implement Node, and it wouldn't really make sense for it to do so.

Related

Do Item custom properties share the same limitations as extended properties?

The documentation mentions that extended properties are a finite resource in a user's mailbox, and exceeding this limit will result in unexpected errors when trying to create new properties.
It is not mentioned explicitly anywhere that I could if item customProperties, as written to through the Office.js client, has the same limitation. Does it?
We plan to optionally write a small amount of data to item customProperties if the user modifies inputs exposed in our Add-in Taskpane in the Outlook client. These properties will later be read by a server consuming changed events through the events delta API.
Will we eventually run into issues with this approach if we don't implement some sort of "garbage collection" of no longer used customProperties?
Item custom Properties are extended properties https://learn.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-oxcext/4cf1da5e-c68e-433e-a97e-c45625483481?redirectedfrom=MSDN
So you have one extended property and then the value is a Json Key pair so one Extended property provides multiple custom properties (up to the limitation of the size of the Extended property)
Even if you don't want to use Item Custom properties its a good idea to follow the same approach eg create one extended property for your app and then store what ever combination of property values you need as a JSON structure in the value on the property. Its not a good idea to have your application creating random/multiple custom properties as you will easily exhaust them/create a mess and there is no advantage in doing it that way.

Save global attribute value when new session starts

I have two fields in SAP Fiori App: Template_ID and Offer_ID.
I want to choose value in Offer_ID depending on Template_ID field value.
For solving this problem I've tried to do this steps:
When the user click on Template_ID field in Back-End runs the method:
CL_CUAN_CAMPAIGN_DPC->contentset_get_entityset().
This method has returning paramater et_result. In et_result I have the necessary field temp_id.
For saving temp_id value I created a global attribute in class ZCL_CUAN_CLASS.
ZCL_CUAN_CLASS=>GV_CONTENT = VALUE #( et_result[ 1 ]-temp_ID OPTIONAL ).
I'll use this global attribute as an input parameter for my second method:
CL_CUAN_CAMPAIGN_DPC->GET_OFFER_BY_TEMPLATE().
This method returns to me the internal table with the offer_id, which belongs to my choosen temp_id.
But when the user click on Offer_ID field on Web UI, in debugging I see that my global attribute is blank.
May be it's because of session or something else, but it's blank.
OData is a stateless protocol, meaning the server responds your query, then forgets you were ever there. By definition, this does not allow you to transport main memory content from one request to the next.
User interfaces on the other hand usually require state. It can be gained through one of the following options:
Stateful user interface
As Haojie points out, one solution is to store the data that was selected in the user interface and submit it as a filter criterion back to the server with the next request. Having a stateful user interface is the standard solution for stateless server apps.
Stateful persistence
Another option is to store the data permanently in the server's database, in ABAP preferredly in a business object. This object has a unique identifier, probably a GUID, that you can reference in your requests to identify the process you are working on.
Draft persistence
If not all information is available in one step, such as in a multi-step wizard, should not become "active" right away, or you want to be able to switch devices while working on a multi-step process, drafts are an option. Drafts are regular business objects, with the one specialty that they remain inert until the user triggers a final activation step.
Soft state
For performance optimizations, you can have a look at SAP Gateway's soft state mode, which allows you to buffer some data to be able to respond to related requests more quickly. This is generally discouraged though, as it contradicts the stateless paradigm of OData.
Stateful protocol
In some cases, stateless protocols like OData are not the right way to go. For example, banking apps still prefer to pertain state to avoid that users remain logged in infinitely, and thus becoming vulnerable to attacks like CSRF. If this is the case for you, you should have a look at ABAP WebDynpro for your user interface. Generally, stateful server protocols are considered inferior because they bind lots of server resources for long times and thus cannot handle larger user numbers.
When ther user click on OfferId field, it will start a NEW session and of course what you store as GV_CONTENT in class ZCL_CUAN_CLASS is lost.
What you should do is that for the second request you should send to backend with filter Template_ID so in your CL_CUAN_CAMPAIGN_DPC->GET_OFFER_BY_TEMPLATE() method, you can further process the result by Template_ID.
Or SET/GET Parameter.

How to prevent name clash with user defined properties

I'm using neo4j (but probably this also applies to other databases). The user can give his own key/value pairs. But i also need to define some properties by the system. How do i prevent a name clash (on the key)? I could prefix all the system properties, but it seems a bit weird. Also i could make another node and put all the system properties there, but that might make for some difficult queries. What's a good way to solve this?
Neo4jis property graph.
Basically, there is no magic there. You already mentioned all possible solutions.
From my perspective best solution is - add prefixes to user defined properties (for example #). This will keep queries simple enough, and doesn’t affect any performance problems.
Additionally, if this properties are only for READ and you are never going to run query against them, then you can look into storing JSON with user-defined data in your nodes:
SET n.user_data = ‘{“key”: “value”}’

Apigee Usergrid: Does usergrid allow subcollections?

I understand that in usergrid UI I can create an Individual collection , but it does not allow me to create a collection under a collection. Is there a way of doing that . Otherwise we will be forced to write business logic in the proxy layer which we don't want to do.
With Regards
-S
There is no concept of subcollection, but you can use connections. So you can do something like this:
POST cats/fluffy/hasa/toys/ball
The above would mean that that an entity of type "cat" is connected to an entity of type "toy" that is called "ball" by a connection verb "hasa".
You can also store sub-objects in an individual entity (e.g. full JSON is supported). If you want to describe your use-case a bit more, I can maybe recommend other ways to structure your data.

REST URL naming convention /items/{id} vs /items?id={id}

I understand that in MVC pattern and in REST services it is common to use URIs like /items/{id} but what is bad thing about using query parameters in the URI?
GET /items/{id} vs GET /items?id={id}
Further, lets say an entity has 'referenceId' field that points to some related (say parent) entity, and I need to create REST service to get all items for parent entity, which way is better:
GET(POST) /items/parent/{parentId}
or
GET(POST) /items?parent={parentId}
Will be grateful for insights that would help to resolve my subjective issues on constructing URLs for REST services.
I would use the following schemes.
/items/id
This uniquely addresses a resource of items with id id. We are not using parameters as a parameter to uniquely address this resource (as is the case with the other option). Just as
miguelcobain suggests.
/parent/id/items
Here id is an id to uniquely address a resource of parent and from those we collect/retrieve the items it references. From what you have said in the question it seems that parent references multiple items, like a container or collection.
The convention I use for this is to narrow down the scope going from left to right. Therefore in case items could be active or inactive. Thusly items have a property or attribute to be active or inactive. Narrowing down on this I get the following scheme:
/items/active
/parent/id/active
For your first question:
/items/{id} should retrieve a single resource with the specified id or 404 if it doesn't exist.
/items/?id={id} should retrieve an array (even if only one in the array) because you are querying the collection.
For your second question:
I agree with #miguelcobain's assessment - if the item is a specific resource/entity, just use the proper resource path to retrieve it.
To make this easier on the consumer, create a link header with rel="parent" and/or include the uri in the child resource. For an example of link headers, see GitHub's pagination api.
Of course, REST principles don't care about aesthetic details on URLs. It just imposes that every resource should be uniquely addressable.
Furthermore, using the query parameters to uniquely address something "kind of" violates the semantics of a "parameter", doesn't it? A parameter should be something optional, something additional and parameterized. Something like a detailed search on a collection of items, for example.
What you wrote may make sense in some cases. It depends.
In your example, is the item really a resource? If not, you could just do GET(POST) /parents/{parentId}.
If parent is, say, a boolean, and you want to search the items that have parent equals to true, then using the parameters makes sense. But since you're explicitly saying that you want a parent with a specific id, I assume that parent is a resource itself and I would uniquely address that resource using your option 1.
I hope I made myself clear.
It seems to me there are no rules to follow.
items/{id} - this convention is suitable for GET item by given id. If user doesn't provide id then it returns 404 status code.
items/id={id}&name={name} - this type of convention is suitable for search multiple items by given criteria. If no items are found, it is not a 404 situation, you simply say "I successfully found nothing matching your search criteria"

Resources