Allow exporting queries via persistConfig while retaining operation text rather than id - relayjs

I'm attempting to "export" all queries in our Relay codebase from relay-compiler by using the following relay.config.json:
{
"persistConfig": {
"file": "queryMap.json"
}
}
The relay-compiler only performs this step in addition to rewriting all queries in __generated__/ used by the app from "text" to "id", expecting the app to send the query identifier as doc_id parameter with requests, rather than the full query as a query parameter (see Relay docs).
I only want to export the query map, but still continue using the query "text" in the app. That's both for developer ergonomics (easier to reason about queries you can see in the network panel), but most importantly because our server (Hasura) doesn't support persisted queries. The goal is to import the query map into Hasura as an allow-list for security purposes instead.
I'm not too fluent in Rust, but looking through the source code it sounds like that would be a new feature request for the relay-compiler?

Related

Is there a way to Bulk extract contact details out of Oracle Eloqua's API?

I am trying to extract a large amount of details out of our Eloqua system using it's API and got this API to work perfectly for single IDs: https://docs.oracle.com/en/cloud/saas/marketing/eloqua-rest-api/op-api-rest-1.0-data-contact-id-get.html
The problem is that I need to run this for a large number of IDs and it will require alot in order to run it for the entire population. Is there any bulk APIs that can extract all of the following details out of Eloqua/Contact for the entire population? I don't see any on that pages documentation that meet this need under the Bulk section.
contactid, company, employees, company_revenue, business_phone, email_address, web_domain, date_created, date_modified, address_1, address_2, city, state_or_province, zip_or_postal_code, mobile_phone, first_name, last_name, title
It's a multi-step process with the Bulk API, typically in the following fashion:
Get a list of the current internal field names - useful for creating your export definition
Create an export definition and post it here. There is a useful example on the page, you do not need a filter criteria. Store the export ID somewhere
Using your export definition id, create a sync. It will gather the data in the background and prepare it for you. Take note of the sync ID provided in the initial response.
Check on the sync status with your sync ID here. It should only take a couple of minutes - and there is a callback url option as well in the previous step, if you don't want to keep polling.
Once your data is ready, use that sync id and request the data. Depending on how many rows were retrieved, you might need to paginate through the results using the offset query param. By default it will give you JSON, but I usually choose CSV (specify in the header).
If you need updated data, feel free to create a new sync using the same export definition id. You do not need to create a new export definition each time.

How to get proper results for these queries?

Need to execute and return 1st order detail alone for each order. Below doesn't work
https://services.odata.org/Experimental/Northwind/Northwind.svc/Customers?$expand=Orders($expand=Order_Details;$top=1)
Need to filter records based on order id. Below doesn't work and throws "Term 'Orders($expand=Order_Details)$filter=OrderID eq '10643'' is not valid in a $select or $expand expression"
https://services.odata.org/Experimental/Northwind/Northwind.svc/Customers?$expand=Orders($expand=Order_Details)$filter=OrderID eq '10643'
Invalid but returned results
https://services.odata.org/Experimental/Northwind/Northwind.svc/Regions?expand=Order_Details
https://services.odata.org/Experimental/Northwind/Northwind.svc/Regions?expand=Territories
Not Returning Childrens
https://services.odata.org/Experimental/Northwind/Northwind.svc/Products?&expand=Suppliers
https://services.odata.org/Experimental/Northwind/Northwind.svc/Regions?&expand=Territories
https://services.odata.org/Experimental/Northwind is no longer 'Best Practise'
It's a bold statement, but this question proves that many advanced query features have not been fully or properly implemented in the published service.
While many developers may use it to practise OData query concepts, given that the OData implementation is largely up to the developers and the version of the packages they use, it is probably a of more commercial value if you query against a live or a dev implementation of the actual service that you want to query.
The following is an analysis of OPs queries and how to achieve the desired response according the the OData-V4 specification and verified against a deployed API that utilises the following NuGet packages:
Microsoft.AspNet.OData v7.3.0
Microsoft.OData.Core v7.6.2
The actual API that I used for testing is proprietary and cannot be published here.
According to the spec, you have to move the $top specifier to the Order_Details expansion.
https://services.odata.org/Experimental/Northwind/Northwind.svc/Customers?
$expand=Orders($expand=Order_Details($top=1))
However:
https://services.odata.org/Experimental/Northwind does not correctly implement $top query option within expansion as defined in 5.1.3 System Query Option $expand
Query options can be applied to an expanded navigation property by appending a semicolon-separated list of query options, enclosed in parentheses, to the navigation property name. Allowed system query options are $filter, $select, $orderby, $skip, $top, $count, $search, and $expand.
$top is however supported in the ODataLib v7+ (.Net) implementation of OData v4. So the syntax is correct, but you should check with your API developers for their opinion if your queries with this syntax do not work.
NOTE: When using $top you should also use $orderbyto ensure that the query results are reliable and reproducable:
https://services.odata.org/Experimental/Northwind/Northwind.svc/Customers?
$expand=Orders($expand=Order_Details($orderby=ProductID;$top=1))
To apply multiple query options within an expansion, you must separate then with a semi-colon: ;. However that alone will not prevent other customer records from being returned, so you must also add a root level filter as well, which is complicated by the fact that Orders is a collection. We can use the any function to only return customers that have an order with the specified Id:
Also note that OrderID is numeric, so do not wrap comparison values in quotes
https://services.odata.org/Experimental/Northwind/Northwind.svc/Customers?
$expand=Orders($expand=Order_Details;$filter=OrderID eq 10643)
&$filter=Orders/any(o:o/OrderID eq 10643)
this can be further simplified using parameter alias:
https://services.odata.org/Experimental/Northwind/Northwind.svc/Customers?
$expand=Orders($expand=Order_Details;$filter=OrderID eq #orderId)
&$filter=Orders/any(o:o/OrderID eq #orderId)
&#orderId='10643'
However:
https://services.odata.org/Experimental/Northwind does not correctly implement parameter aliases so you cannot verify the alias syntax against this service.
Also note
that experimental service is not correctly applying the filter to either the root elements or the navigation collection, the syntax shown here does however work against the .Net ODataLib implementations of OData v4.
The reason that your $expand is not working is that you have left off the $ from the parameter name. The OData query interpreter only identifies query options are parameters that start with $.
Eitherway, according to the https://services.odata.org/Experimental/Northwind/Northwind.svc/$metadata#Regions, there is no Order_Details navigation property to $expand on:
<EntitySet Name="Regions" EntityType="NorthwindModel.Region">
<NavigationPropertyBinding Path="Territories" Target="Territories" />
</EntitySet>
So when you try again with the correct syntax:
https://services.odata.org/Experimental/Northwind/Northwind.svc/Regions?$expand=Order_Details
you get the expected message:
Could not find a property named 'OrderID' on type 'NorthwindModel.Region'
The second attempt will work if you put the correct $ in there for the $expand query option:
https://services.odata.org/Experimental/Northwind/Northwind.svc/Regions?$expand=Territories
The OData query parser only looks for the expected query options with the $ prefix, this allows your API logic to still process other non-OData parameters as you see fit to do so. The other parameters therefor are still HTTP Url compliant parameters, the implementation at odata.org doesn't know what to do with them and they are simply ignored.
This is just another variation on the same issue with 3, the $ is missing. (I suspect that this URL was meant to be in 3: https://services.odata.org/Experimental/Northwind/Northwind.svc/Products?$expand=Suppliers)
So while https://services.odata.org/Experimental/Northwind is not 100% reliable, neither are the .Net ODataLib, SAP or MS Dynamics implementations. The spec is evolving and there are many query techniques that are not fully implemented in probably any providers at this stage.
Simply be mindful of this fact and when you run into issues using an API, the first point of contact should be the developers or the community that are supporting that particular API, it will be up to the developers what techniques and packages they use and at the end of the day to what extent they support the protocol as it is specified.

Retrieving More columns as Part of VSTS query

I'm trying to fetch details from VSTS using VSTS query API. So to get all Portfolio Epics I created a custom query and used its ID to get that in JSON format. the query looks like this
https://dev.azure.com/{organization}/{project}/{team}/_apis/wit/wiql/{id}?api-version=5.0-preview.2
But the issue is its not giving me many details about each of the work items in JSON. It only lists the ID and URL. Like this
WorkItems:[
{ID:234,URL:"workitemurl"},
{ID:235,URL:"workitemurl"},
{ID:236,URL:"workitemurl"},
...
]
So if I need more details about an item I need to execute those individual URl for each PE and thus I can get its details. instead of I am just checking is there is any way of getting an ID (keyedinID of each work item along with the ID and URL) like this. Please note KID is a field if we execute the URL separately. So to avoid that extra process, I would like to get that along with the WorkItems.
WorkItems:[
{ID:234,URL:"workitemurl",KID:002},
{ID:235,URL:"workitemurl",KID:023},
{ID:236,URL:"workitemurl",KID:033},
...
]
So how can we make this possible?
The Web UI uses a different API to get query results (/_api/_wit/_query), which allows query+data in a single pass. This is an old __v5 type call, which means it's considered internal.
The proper way to do this now is to first do the query as you're doing it right now and then call /_api/wit/workitems?ids=1,2,3,4 using the IDs from the references you got from the first call. That will also allow you to load the details dynamically and in small batches which will result in a more responsive UI.
See:
https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/work%20items/list?view=azure-devops-rest-4.1

How could execute multiple cypher at a time in neo4j.

I want to execute multiple cypher queries at same time for the brower, how count i execute that. And i am using noe4j version for 2.2.5. My sample query was,
CREATE(n:Taxonomy{UUID:10001, name:"BOSH", classType:"Interface Type", version:"2.2",isDeleted:"0"});
CREATE(n:Taxonomy{UUID:10002, name:"Iaas", classType:"AWS", version:"0.0",isDeleted:"0"});
CREATE(n:Taxonomy{UUID:10003, name:"order lifecycle", classType:"draft order", version:"0.0",isDeleted:"0"});
CREATE(n:IaaSTemplate{UUID:20001, IaasName:"Iaas Template 1",isDeleted:"0"});
CREATE(n:TemplateFunction{UUID:30001, functionName:"bosh target",isDeleted:"0"});
CREATE(n:TemplateFunction{UUID:30002, functionName:"bosh login",isDeleted:"0"});
Batching multiple queries into one is not (yet) supported by the Browser.
However, the specific queries in your question can be easily combined into a single query by:
Removing the n identifier from all the nodes.
Within a single query, an identifier is associated with a specific instance of a node or relationship (ignoring the effect of WITH clauses). But, since you don't actually use the identifier, getting rid of it would allow all the CREATE clauses to co-exist in the same query.
Removing all semicolons (except the last one).
So, this should work:
CREATE(:Taxonomy{UUID:10001, name:"BOSH", classType:"Interface Type", version:"2.2",isDeleted:"0"})
CREATE(:Taxonomy{UUID:10002, name:"Iaas", classType:"AWS", version:"0.0",isDeleted:"0"})
CREATE(:Taxonomy{UUID:10003, name:"order lifecycle", classType:"draft order", version:"0.0",isDeleted:"0"})
CREATE(:IaaSTemplate{UUID:20001, IaasName:"Iaas Template 1",isDeleted:"0"})
CREATE(:TemplateFunction{UUID:30001, functionName:"bosh target",isDeleted:"0"})
CREATE(:TemplateFunction{UUID:30002, functionName:"bosh login",isDeleted:"0"});
Unfortunately Neo4j Browser doesn't support that yet, it's on the long list of things.
You can use the bin/neo4j-shell that connects to a running browser.
Or a project like cycli which is a colorful, auto-complete shell for Neo4j that talks to the http interface and supports auth etc.

webdis server side join

First of all excuse me if I got some concept wrong, this a bit new to me. I have to retrieve a number of objects from a webdis server. The way it is being done at the moment is:
Get all the objects ids (serverUrl/ZRANGE/objects_index/-X/-1)
For each object, get attributes (serverUrl/GET/attributeY_objectIdX)
So if I have X objects with Y attributes I have to perform X * Y + 1 REST calls to get all he data, that seems highly inefficient.
From what I understand Multi is the command to perform a join but is not supported by webdis rest api (see Ideas, TODO on webdis page).
Is there a simpler solution that I am missing?
Should I reorganise the way the data is stored?
Can I use websockets to send a MULTI/EXEC command through json:
jsonSocket.send(JSON.stringify(["MULTI", "EXEC", "GET", "etc..."]));
First, instead of having one key per attribute, you should consider use hash objects, so you get one key per object, associated to several properties. The benefit is you can use the HGETALL command to retrieve all the properties of a given object at once. Instead of having X*Y+1 calls, you have only X+1.
Instead of:
SET user:1:name Didier
SET user:1:age 41
SET user:1:country FR
you could have:
HMSET user:1 name Didier age 41 country FR
Then, webdis supports HTTP 1.1 and websocket pipelining, and Redis server supports pipelining using its own protocol. So it should be possible to send several commands to webdis, wait for the results (which will be returned in the same order) while only paying for a single roundtrip.
For instance, the websocket example provided on webdis page actually performs a single roundtrip to execute two commands:
var jsonSocket = new WebSocket("ws://127.0.0.1:7379/.json");
jsonSocket.onopen = function() {
console.log("JSON socket connected!");
jsonSocket.send(JSON.stringify(["SET", "hello", "world"]));
jsonSocket.send(JSON.stringify(["GET", "hello"]));
};
jsonSocket.onmessage = function(messageEvent) {
console.log("JSON received:", messageEvent.data);
};
You could do something similar, and aggregate several HGETALL commands to retrieve the data by batch of n objects.
Please note that with Redis itself (i.e. without webdis), I would probably recommend the same strategy (pipelining HGETALL commands).

Resources