Node.js and express Rest api to create custom fields routes - javascript

I am working with node.js and express framework for my rest api server.
I have created get routes with query params and working with them.
But I want to make a functionality like facebook graph api where I can send fields with my api routes such as
/me?fields=address,birthday,email,domains.limit(10){id,name,url}
I am thinking of getting the fields from the query parameters and then splitting them based on , such as
const fields = req.query.fields;
let fieldsArray = fields.split(',');
But how can I pass the sub object attributes and retrieve them from the route like domain field from the above example.
/me?fields=address,birthday,email,domains.limit(10){id,name,url}

If you use a dot-notation like so
/me?fields=address,domains.id,domains.name&dbQueryFilters=domains.limit=10
It could mean:
I want these fields in my response:
address
domains:
id
name
Use these to query the db:
domains:
limit :10
You can add/remove such query variables until it explicitly conveys what your API does while still being very basic. It's always in your best interest to keep things simple and basic.
On the nodeJS side, you can use a library like flat to unflatten the query object:
var fields = flat.unflatten(req.query.fields)

Try sending out the request like:
/me?fields=address,birthday,email,domains.limit%2810%29%7Bid%2Cname%2Curl%7D
There is code for every special character you can get it by doing:
escape("domains.limit(10){id,name,url}") // Returns domains.limit%2810%29%7Bid%2Cname%2Curl%7D
More details: JavaScript escape() Function
Hope this solves your issue.

Related

Multiple endpoints in same query

It works perfectly, with a single endpoint.
With apollo-link-rest, I have made a client that looks like this
const restLink = new RestLink({ uri: "https://example.com/" })
And export the client with a new ApolloClient({...})
Now to the question
On the same server https://example.com/, there are multiple endpoints, all with same fields but different data in each
The first query that works look like this
export const GET_PRODUCTS = gql`
query firstQuery {
products #rest(type: "data" path: "first/feed") { // the path could be second/feed and it will work with different data
id
title
}
}
`
I want all these different path into one and same json feed, because they all have the same fields, but with different data
Using aliases
You can (should be possible) use standard method to make similar queries - get many data (result) nurmally available as the same shape (node name). This is described here.
{
"1": products(....
"2": products(....
...
}
Paths can be created using variables
Results can be easy combined by iterating over data object. Problem? Only for fixed amount (not many) endpoints as query shouldn't be generated by strings manipulations.
Multiple graphql queries
You can create queries in a loop - parametrized - using Promise.all() and apollo-client client.query(. Results needs to be combined into one, too.
Custom fetch
Using custom fetch you can create a query taking an array of paths. In this case resolver should use Promise.all() on parametrized fetch requests. Combined results can be returned as single node (as required).
Bads
All these methods needs making multiple requests. Problem can be resolved by making server side REST wrapper (docs or blog).

Postman - GUIDS

As part of my API call I need to pass in random ids in the body, currently I am creating the IDs using GUID in C# but its proving to be really time consuming as I need to test APIs in large batches. I am trying to figure out if it's possible to create a GUID in Postman on the fly and save them into a variable and pass it into require parameters through the API call.
I came across few resources like
What is {{$guid}} used for in Postman?
https://www.toolsqa.com/postman/guid-in-postman/
First issue I am having is that I want to create the ID without the dash, so instead of b3d27f9b-d21d-327c-164e-7fb6776f87b0 I want b3d27f9bd21d327c164e7fb6776f87b0.
Secondly, I want to save these into a environment variable and pass it where it's required e.g.
In body as raw text I need to pass:
{
"clientID":{{id}},
"clientpassword":{{password}},
}
In the 'Tests', I currently have this script but I can't manage to get it working.
let id = {{$guid}};
let password = {{$guid}};
I have created 2 global variables called id and password
Also, currently I have these in the 'Tests' section of the postman, I see there is also a pre-request script. In which should I put this?
EDIT
Also, another thing I am trying to do is, sometimes I need to search for a user by providing a client id in different places. Is it possible to put the id and password in one place where I can either update it manually or by running the guid, so that I don't need to update it in each API test I do but rather it should grab it from one place where I updated it.
You do something like this in the Pre-request Script sandbox:
let idGuid = pm.variables.replaceIn('{{$guid}}')
let passwordGuid = pm.variables.replaceIn('{{$guid}}')
pm.variables.set("id" , idGuid.replace(/-/g, ''))
pm.variables.set("password" , passwordGuid.replace(/-/g, ''))
These would then resolve the variables that you have placed within the request body.
Not the most efficient solution but it would create the values you would like.
There are also a number of other fake data variables available for you to use in the application:
https://learning.getpostman.com/docs/postman/scripts/postman_sandbox_api_reference/#dynamic-variables

How to use the WP REST API with a custom endpoint using the Javascript library?

I have a custom endpoint which does nothing but return a test string. I can reach that endpoint by navigating to mydomain.com/wp-json/mytools/v1/method/get_user_data and it correctly returns my test string, but, I want to be able to reach that endpoint using Javascript, and, I read that the wp-api handles authentication automatically so I should be able to get a current logged in user with this method.
What I need is to be able to use something like wp.api.mytools.method.get_current_user and get the information for the currently logged in user. Is this even possible?
This is the way I created the endpoint:
register_rest_route( 'mytools/v1', '/method/(?P<method>[\w]+)', array(
'methods' => 'GET',
'callback' => 'invoke_method',
));
And this is the invoke_method function:
function invoke_method( WP_REST_Request $request ) {
return wp_get_current_user();
}
This functionality is already implemented by WordPress at the WP_REST endpoint '.../wp-json/wp/v2/users/me. In addition to the logged-in cookie WP REST authentication requires a nonce specified by a query argument '_wpnonce'. The value of this nonce is generated by calling wp_create_nonce( 'wp_rest' ). A normal WordPress front-end page will include the script .../wp-includes/js/api-request.js. This script will define a global wpApiSettings.nonce which will contain this nonce so you can use the request '.../wp-json/wp/v2/users/me?_wpnonce=' + wpApiSettings.nonce. So, you can use jQuery.get().
jQuery.get(
'.../wp-json/wp/v2/users/me?_wpnonce=' + wpApiSettings.nonce,
function( response ) {
var userData = JSON.parse( response );
) }
);
If you only want to get the current user I don't think you need Backbone.js. Backbone.js will synchronise collections and models using CRUD and you are not doing any of this.
Overall, yes, it IS possible.
Specifically, if wp-api if you're referring to the node-wpapi JS library, then yes it does handle authentication. Otherwise, you will need to implement Authentication yourself, using Cookie, Nonce, Basic-Auth or JWT.
For second part, it is definitely possible to use something like wp.api.mytools.method.get_current_user to get information. What you'll need is a client library (node-wpapi), and extend it to include your classes and functions, such as mytools and method.
Hope this helps to clarify

DocumentDB: Access document by database name, collection ID and document ID in Node.js

I'm making my first application using DocumentDB. I'm developing an API for it in Node.js. As others have noted, the DocumentDB APIs are very confusing and appear to require convoluted code to achieve simple things.
My API will allow me to access data in the database with a URL of the form http://<host>/data/<databaseName>/<collectionID>/<documentId>/<pathToData>. If <pathToData> is empty, then I will get the whole document as a JSON object.
I want a function with the signature GetDocument(databaseName,collectionID,documentId,callback), where callback is a function that takes the particular document as a JavaScript object. What implementation of GetFunction achieves my goal?
The DoQmentDB library makes for a trivial solution.
// dbClient: require('documentdb').DocumentClient; new DocumentClient(host,options);
// callback: function(document)
function getDocument(dbClient,databaseId,collectionId,documentId,callback) {
var DoQmentDB = require('doqmentdb');
var db = new DoQmentDB(dbClient,databaseId);
var collection = db.use(collectionId);
collection.findById(documentId).then(callback);
}
You first need your method to initialize a documentclient object with the database and collection parameters, which you do with the readorcreatedatabase and readorcreatecollection methods, as showcased in the documentation. Once you have that object initialized, you can query specific objects by document id or by a custom query string.
Ideally, you should cache those database and collection objects upon first request, so that you don't hit the db asking for the same information upon every single request you issue

Jsplumb add connection programmatically using endpoints

My requirement is like, I am adding two endpoints using jsplumb.addEndPoint for two containers named 'container0' and 'container1'.
Now I need to link the two end points using a connector programmatically but the jsplumb.connect creates a new endpoint and connecting and is not using the end point which I have created using jsplumb.addEndpoint .
How could I connect these two end points? Also I just want to add a connection if the connection is not already there for the end points?
To connect using already existing endpoints you can make use of the Uuid's of the endpoints:
jsPlumb.ready(function () {
var e0 = jsPlumb.addEndpoint("container0",{uuid:"ep1"}), //set your own uuid for endpoint for later access.
e1 = jsPlumb.addEndpoint("container1",{uuid:"ep2"});
jsPlumb.connect({ uuids:[e1.getUuid(),e2.getUudi()] }); // (or) jsPlumb.connect({ uuids:["ep1","ep2"] });
});
According to the API jsPlumb.connect() can receive
array of UUIDs of the two Endpoints
but it's not the only way to connect endpoints as there's also another way (which is more common as it's used to connect two objects) with source and target parameters who can receive String or Object (as a DOM object) or directly an Endpoint (which is not the same as a DOM selector of an endpoint, for instance it can be let firstEndpoint = jsPlumb.addEndpoint()).
So if, like me, you don't want to use universally unique identifier you can stick to classical source target and give endpoint as parameters.
jsPlumb.connect({ source: firstEndpoint, target: jsPlumb.selectEndpoints() });

Categories

Resources