Expose GraphQL schema from non-JS server to a JS client - javascript

I have a GraphQL server implemented in Java and a JavaScript client querying it. What I don't like is that the client has to just know the schema and can not get it from the server instead and dynamically build queries against it.
Now, I understand GraphiQL somehow does just that, but I'm guessing it's because its backend is also written in JavaScript so both the client and server can use it. My schema is defined in Java, but there might be a way to automatically generate a JavaScript representation that the client could use.
Does such a thing already exist?

Now, I understand GraphiQL somehow does just that, but I'm guessing it's because its backend is also written in JavaScript so both the client and server can use it.
Actually, (fortunately) this is not the case. It is written in Javascript, but it need not be to achieve this behavior.
I've got some great news for you...
Introspection!
One of the awesome things about GraphQL is that, in fact, the client doesn't have to know anything about the schema, because it can just query the server for it using introspection. In fact, GraphiQL will use this automatically if you don't provide a schema explicitly to automagically populate it.
From the Props section of the GraphiQL README:
schema: a GraphQLSchema instance or null if one is not to be used. If undefined is provided, GraphiQL will send an introspection query using the fetcher to produce a schema.
The official GraphQL Introspection docs will give you lot more information and sample queries. Their example of querying their Star Wars example schema:
{
__schema {
types {
name
}
}
}
This returns the names of all of the types. Introspection is part of the GraphQL spec, so every GraphQL server should be able to do it out of the box: you don't need to explicitly add any functionality.

Related

How to filter and select specific fields from mongodb in a GET request?

I have just started working with mongoose/mongodb and node.js to build the backend of a react native app I am working on. I'm getting fairly comfortable with querying documents in the database from node but how do I set those "filters" in a GET request (using fetch) from the front end?
If a user applies a filter to a list to only return products of a certain price, how do I get that filter from the client side over to the server side so node can make the proper query on the database?
Same question for if I only want to return specific fields as opposed to returning every field in a mongodb document. How can I let the backend know what fields to return from the client side?
Hopefully that all makes sense, like I said I'm very new to both mongo and node so I apologize if my explanations are not the best.
Thank you to anyone who can help!
What you're looking for is a query language - a syntax for conveying the parameters of a query to a server. There are several options.
Some sites decide to only support simple queries. The simplest query language, in this case, is the GET query string. For instance, if you're building an on-line store, your customers will typically need to search for products by name and by category, and so you may end up with two query string parameters that you support in URLs, like this:
/products?category=clothes&search=t-shirt
Then, your application must process each of these parameters independently - your back-end must know how to turn this into a MongoDB query. For example:
products.find({
category: { $eq: req.query.category },
$text: { $search: req.query.search }
// similarly, you could accept params such as "pricemin" and "pricemax"
// and construct a { $gt, $lt } query
});
For more complex systems or applications that require more flexibility, you can allow the client to construct a complete query on their own and pass that to the back-end for evaluation. Multiple solutions exist that let you achieve this - GraphQL is a popular choice lately due to its good tooling support and ease of use. Another well-known solution is OData, which is used in some high-profile APIs, such as Microsoft Graph API.
If using an advanced query language, your back-end will always need to translate between the format that's sent to the server and the format that the database speaks. The simplest, non-generic example is the code snippet above - though batteries-included solutions will normally come with their own translators, so you may not need to write any code yourself if a package exists that does that for you.

Having a fixed response structure with node.js and Express

We have recently started using Node.js for our API server instead of Java. Apart from all the good things which Node.js provides, one thing I miss the most is having a proper response object for an API.
Since Javascript being dynamically typed languages, objects can be created on the fly while returning the response. This is in contrast to Java, where I can have a class , an instance of which will be serialized in the response. I can anytime lookup this class to determine what the response of the API will be.
Is there such a design pattern in Node.Js / Javascript. We would like our API's to have strict conformance to such templated object.
You can make them yourself.
If you're using ES6 for example, you can have various error and response modules, and perform your own validation in the class that creates those responses.
For example,
// sample-response.js
class SampleResponse {
constructor(message) {
// validate `message` somehow
this.data = message
}
}
module.exports = {
SampleResponse
}
Then however you're structuring your HTTP interface, you can send back whichever response you'd like (for example, with Express):
res.send(new SampleResponse(message))
Same goes with errors, etc. You're not necessarily limited by a lack of types with JavaScript, you just have to enforce things differently.
If you're not using ES6, you can do something like this:
module.exports = {
SampleResponse: function(message) {
// do some validation
return { data: message }; // or whatever you want
}
};
You can use Flow or TypeScript for you code.
You can use contract testing tools. Depending on the contract for your REST API:
abao for RAML
dredd for api blueprint
SoapUI for Swagger
My choice is to use TypeScript and Abao+RAML.

Keeping a client-side sync of Sails.js collection, using sockets

I very much like Meteor's pub/sub. I wonder if there is a way to get a similar workflow, using sails.js or just a socket library in general.
In particular, what I would like to be able to do is something along the lines of:
// Server-side:
App.publish('myCollection', -> collection.find({}))
// Client-side:
let myCollection = App.subscribe('myCollection')
let bob = myCollection.find({name: 'Bob'})
myCollection.insert({name: 'Amelie'}, callback)
All interaction with the server should happen in the background.
I very much like Meteor's pub/sub. I wonder if there is a way to get a similar workflow, using sails.js or just a socket library in general
Basically yes, at least about realtime sync between backend and frontend. Let's review what meteor's have and answer point by point.
Pub/sub
The Pub / Sub concept, as stated by Sabbir, is also supported by sails.js. Though the basics are slightly different :
In meteor, the client can subscribes to everything he wants, and the server control what it receives by only publishing to who he wants;
whereas in sails.js, the server both does subscribe some clients sockets and publish to all binded sockets
Note that, by default:
meteor contains the autopublish package that just notify every client without any kind of filtering. To acheive some filtering, you have to meteor remove autopublish then you can handle what will your client receive by adding a mongo request to it, like explained here.
sails by default, on its automatic "select" blueprints actions, auto-subscribes the calling socket to the events on the objects returned by the "select".
As a server-side conclusion:
Subscribe: just call findor findOne blueprint default action, through a socket (attaching some where filters or not) and your socket will automatically be subscribed to every events concerning returned objects => you don't have to code anything on the server, in most cases, for the Subscribe logic.
Publish: every blueprint default actions (create, update, destroy, add, remove) auto-publish to subscribed sockets => you don't have to code anything on the server, in most cases, for the Publish logic.
(Though, if you find yourself implementing some manual controller actions, sails API helps you publishing and subscribing easily)
Client handling
Therefore, with both meteor and sails, clients only receive what they're supposed to receive. Time for front-end now.
Philosophy
meteor in one hand, with it's isomorphic dimension, does provide a front-end connector by nature, exposing it's data-bound collections.
sails on the other hand, is front-end agnostic, and can be attacked by any http REST connector (JS or not), such as $http, $resource, or more advanced ones like Restangular.
Though, being aware of the complexity using raw sockets on their API (when it comes to session, CORS, CSRF and stuff), they developped a javascript socket.io wrapper called sails.io.js designed to be REST-like-over-socket, and just works like a charm.
Basically, The main difference is that meteor is one step higher-level than sails, because it provides the logic of syncing collections and objects.
All interaction with the server should happen in the background.
sails.io.js, the official front-end component, is just not that high-level. When it comes to Angular.js.
Though, you can find some community connectors that aim to, kinda, provide the same feature as mongo data-bound collections and objects. There is sails-resource, spinnaker or angular resource sails. I tried both of them, and I should say that I was disapointed. The abstraction level is so high that it just becomes annoying, IMHO. For example, with not-very-RESTful-friendly custom actions, like a login, it becomes very hard to adapt it for your needs.
==> I would advice to use a low-level connector, such as angularSails or (my prefered) https://github.com/janpantel/angular-sails, or even raw sails.io.js if you're not using Angular.
Edit: just foun a backbone version, by the sails' creator
It just works great, and believe me, the "keep my collection in sync with that socket" code is so ridiculous, that finding a module for this is just not worth it.
Some code please, stop talking
In particular, what I would like to be able to do is something along the lines of:
Server
Meteor
# Server-side:
App.publish('myCollection', -> collection.find({}))
Sails
//Nothing to do, just sails generate api myCollection
Client
Meteor
# Client-side:
myCollection = App.subscribe('myCollection')
Sails, with sails.io.js
(Here using lodash for convenience)
var myCollection;
sails.io.get('/myCollection').then(
function(res) {
myCollection = res.data;
},
function(err) {
//Handle error
}
);
sails.io.on('myCollection').function(msg) {
switch(msg.verb) {
case 'created':
myCollection.push(msg.data);
break;
case 'updated':
_.extend(_.find(myCollection, 'id', msg.id), msg.data);
break;
case 'destroyed':
_.remove(myCollection, 'id', msg.id);
break;
};
});
(I leave the find where and create to your imagination with [the doc])
All interaction with the server should happen in the background.
Well, Sails, only for angular, with sails ressources
I'm not pretty used to that process, so I leave you reading here or here, but once again I'd choose manual .on()method.
Since I asked this question, I've learned a few things and some new projects have popped up. I decided against sails.io, because when developing with React.js, most of the community's weight is behind webpack, but sails.io uses gulp. I realize these can be used together and there is even an npm package for this, but I wasn't too keen on making my stack bigger than it had to be, so I went with a simple express.js server that I could tailor to my needs.
In order to sync my data, I'm using rethinkdb which allows me to asynchronously watch the database for changes and then publish the changes to the clients through websockets.
I've set up a simple script where I keep an instance of a baobab tree on both the client and the server.
When the tree gets modified on the server, it sends transaction data to the appropriate clients through the websocket
The client merges the transaction with the tree.
This method does not make use of local storage and keeps the data in memory in the node.js process. The data in the transaction is also quite redundant.
The future plan has always been to set something up using redis and local storage ...
... until yesterday when I found deepstream.io!
This is a tool that does exactly what I want and need! Nothing more, nothing less.
Another project worth mention is meatier: "like meteor, but meatier". It is composed of many other well supported open source projects, so you could even pick and choose.

How to customize the OData server using JayData?

I'm quite new to JayData, so this may sound like a stupid question.
I've read the OData server tutorial here: http://jaydata.org/blog/install-your-own-odata-server-with-nodejs-and-mongodb - it is very impressive that one can set up an OData provider just like that. However the tutorial did not go into details about how to customize the provider.
I'd be interested in seeing how I can set it up with a custom database and how I can add a layer of authentication/authorization to the OData server. What I mean is, not every user may have permissions to every entity and not every user has the permission to add new entities.
How would I handle such use cases with JayData?
Thanks in advance for your answers!
UPDATE:
Here are two posts that will get you started:
How to use the odata-server npm module
How to set up authentication/authorization
The $data.createODataServer method frequently used in the posts is a convenience method that hides the connect/express pipleline from you. To interact with the pipeline examine the method body of $data.createODataServer function found in node_modules/odata-server folder.
Disregard text below
Authentication must be solved with the connect pipeline there are planty of middleware for that.
For authorization EntityContext constructor accepts an authorization function that must be promise aware.
The all-allow authorizator looks like this.
function checkPerm(access, user, entitysets, callback) {
var pHandler = new $data.PromiseHandler();
var clbWrapper = pHandler.createCallback(callback);
var pHandlerResult = pHandler.getPromise();
clbWrapper.success(true); // this grants a joker rw permission to everyone
//consult user, entitySet and acces to decide on success/error
//since you return a promise you can call async stuff (will not be fast though)
return pHandlerResult;
}
I have to consult with one of the team members on the syntax that let you pass this into the build up process - but I can confirm this is doable and is supported. I'll get back with the answer ASAP.
Having authenticated the user you can also use EntityContext Level Events to intercept Read/Update/Create/Delete operations.
$data.EntityContext.extend({
MySet: { type: $data.EntitySet, elementType: Foobar,
beforeDelete: function(items) {
//if delete was in batch you'll get multiple items
//check items here,access this.request.user
return false // deny access
}
});
And there is a declarative way, you can annotate Role names with permissions on entity sets, this requirest that your user object actually has a roles field with an array of role names.
I too have been researching oData recently and as we develop our platform in both node and C# naturally looked at JayStorm. From my understanding of the technical details of JayStorm the whole capability of Connect and Express are available to make this topic possible. We use Restify to provide the private API of our platform and there we have written numerous middleware modules for exactly this case.
We are using JayData for our OData Service layer also, and i have implemnment a very simple basic authentication with it.
Since the JayData is using Express, so we can leverage Express' features. For Basic Auth, the simplest way is:
app.use(c.session({ secret: 'session key' }));
// Authenticator
app.use(c.basicAuth('admin', 'admin'));
app.use("/odata.svc", $data.JayService.OData.Utils.simpleBodyReader());
you also can refer to this article for more detail for authentication with Express: http://blog.modulus.io/nodejs-and-express-basic-authentication
Thanks.
I wrote that blogpost, I work for JayData.
What do you mean by custom database?
We have written a middleware for authentication and authorization but it is not open source. We might release it later.
We have a service called JayStorm, it has a free version, maybe that is good for you.
We probably will release an appliance version of it.

Publish data from browser app without writing my own server

I need users to be able to post data from a single page browser application (SPA) to me, but I can't put server-side code on the host.
Is there a web service that I can use for this? I looked at Amazon SQS (simple queue service) but I can't call their REST APIs from within the browser due to cross origin policy.
I favour ease of development over robustness right now, so even just receiving an email would be fine. I'm not sure that the site is even going to catch on. If it does, then I'll develop a server-side component and move hosts.
Not only there are Web Services, but nowadays there are robust systems that provide a way to server-side some logic on your applications. They are called BaaS or Backend as a Service providers, usually to provide some backbone to your front end applications.
Although they have multiple uses, I'm going to list the most common in my opinion:
For mobile applications - Instead of having to learn an API for each device you code to, you can use an standard platform to store logic and data for your application.
For prototyping - If you want to create a slick application, but you don't want to code all the backend logic for the data -less dealing with all the operations and system administration that represents-, through a BaaS provider you only need good Front End skills to code the simplest CRUD applications you can imagine. Some BaaS even allow you to bind some Reduce algorithms to calls your perform to their API.
For web applications - When PaaS (Platform as a Service) came to town to ease the job for Backend End developers in order to avoid the hassle of System Administration and Operations, it was just logic that the same was going to happen to the Backend. There are many clones that showcase the real power of this strategy.
All of this is amazing, but I have yet to mention any of them. I'm going to list the ones that I know the most and have actually used in projects. There are probably many, but as far as I know, this one have satisfied most of my news, whether it's any of the previously ones mentioned.
Parse.com
Parse's most outstanding features target mobile devices; however, nowadays Parse contains an incredible amount of API's that allows you to use it as full feature backend service for Javascript, Android and even Windows 8 applications (Windows 8 SDK was introduced a few months ago this year).
How does a Parse code looks in Javascript?
Parse works through classes and objects (ain't that beautiful?), so you first create a specific class (can be done through Javascript, REST or even the Data Browser manager) and then you add objects to specific classes.
First, add up Parse as a script tag in javascript:
<script type="text/javascript" src="http://www.parsecdn.com/js/parse-1.1.15.min.js"></script>
Then, through a given Application ID and a Javascript Key, initialize Parse.
Parse.initialize("APPLICATION_ID", "JAVASCRIPT_KEY");
From there, it's all object manipulation
var Person = Parse.Object.extend("Person"); //Person is a class *cof* uppercase *cof*
var personObject = new Person();
personObject.save({name: "John"}, {
success: function(object) {
console.log("The object with the data "+ JSON.stringify(object) + " was saved successfully.");
},
error: function(model, error) {
console.log("There was an error! The following model and error object were provided by the Server");
console.log(model);
console.log(error);
}
});
What about authentication and security?
Parse has a User based authentication system, which pretty much allows you to store a base of users that can manipulate the data. If map the data with User information, you can ensure that only a given user can manipulate specific data. Plus, in the settings of your Parse application, you can specify that no clients are allowed to create classes, to ensure innecesary calls are performed.
Did you REALLY used in a web application?
Yes, it was my tool of choice for a medium fidelity prototype.
Firebase.com
Firebase's main feature is the ability to provide Real Time to your application without all the hassle. You don't need a MeteorJS server in order to bring Push Notifications to your software. If you know Javascript, you are half way through to bring Real Time magic to your users.
How does a Firebase looks in Javascript?
Firebase works in a REST fashion, and I think they do an amazing job structuring the Glory of REST. As a good example, look at the following Resource structure in Firebase:
https://SampleChat.firebaseIO-demo.com/users/fred/name/first
You don't need to be a rocket scientist to know that you are retrieve the first name of the user "Fred", giving there's at least one -usually there should be a UUID instead of a name, but hey, it's an example, give me a break-.
In order to start using Firebase, as with Parse, add up their CDN Javascript
<script type='text/javascript' src='https://cdn.firebase.com/v0/firebase.js'></script>
Now, create a reference object that will allow you to consume the Firebase API
var myRootRef = new Firebase('https://myprojectname.firebaseIO-demo.com/');
From there, you can create a bunch of neat applications.
var USERS_LOCATION = 'https://SampleChat.firebaseIO-demo.com/users';
var userId = "Fred"; // Username
var usersRef = new Firebase(USERS_LOCATION);
usersRef.child(userId).once('value', function(snapshot) {
var exists = (snapshot.val() !== null);
if (exists) {
console.log("Username "+userId+" is part of our database");
} else {
console.log("We have no register of the username "+userId);
}
});
What about authentication and security?
You are in luck! Firebase released their Security API about two weeks ago! I have yet to explore it, but I'm sure it fills most of the gaps that allowed random people to use your reference to their own purpose.
Did you REALLY used in a web application?
Eeehm... ok, no. I used it in a Chrome Extension! It's still in process but it's going to be a Real Time chat inside a Chrome Extension. Ain't that cool? Fine. I find it cool. Anyway, you can browse more awesome examples for Firebase in their examples page.
What's the magic of these services? If you read your Dependency Injection and Mock Object Testing, at some point you can completely replace all of those services for your own through a REST Web Service provider.
Since these services were created to be used inside any application, they are CORS ready. As stated before, I have successfully used both of them from multiple domains without any issue (I'm even trying to use Firebase in a Chrome Extension, and I'm sure I will succeed soon).
Both Parse and Firebase have Data Browser managers, which means that you can see the data you are manipulating through a simple web browser. As a final disclaimer, I have no relationship with any of those services other than the face that James Taplin (Firebase Co-founder) was amazing enough to lend me some Beta access to Firebase.
You actually CAN use SQS from the browser, even without CORS, as long as you only need the browser to send messages, not receive them. Warning: this is a kludge that would make my CS professors cry.
When you perform a GET request via javascript, the browser will always perform the request, however, you'll only get access to the response if it was from the same origin (protocol, host, port). This is your ticket to ride, since messages can be posted to an SQS queue with just a GET, and who really cares about the response anyways?
Assuming you're using jquery, your queue is https://sqs.us-east-1.amazonaws.com/71717171/myqueue, and allows anyone to post a message, the following will post a message with the body "HITHERE" to the queue:
$.ajax({
url: 'https://sqs.us-east-1.amazonaws.com/71717171/myqueue' +
'?Action=SendMessage' +
'&Version=2012-11-05' +
'&MessageBody=HITHERE'
})
The'll be an error in the console saying that the request failed, but the message will show up in the queue anyways.
Have you considered JSONP? That is one way of calling cross-domain scripts from javascript without running into the same origin policy. You're going to have to set up some script somewhere to send you the data, though. Javascript just isn't up to the task.
Depending in what kind of data you want to send, and what you're going to do with it, one way of solving it would be to post the data to a Google Spreadsheet using Ajax. It's a bit tricky to accomplish though.Here is another stackoverflow question about it.
If presentation isn't that important you can just have an embedded Google Spreadsheet Form.
What about mailto:youremail#goeshere.com ? ihihi
Meantime, you can turn on some free hostings like Altervista or Heroku or somenthing else like them .. so you can connect to their server , if i remember these free services allows servers p2p, so you can create a sort of personal web services and push ajax requests as well, obviously their servers are slow for free accounts, but i think it's enought if you do not have so much users traffic, else you should turn on some better VPS or Hosting or Cloud solution.
Maybe CouchDB can provide what you're after. IrisCouch provides free CouchDB instances. Lock it down so that users can't view documents and have a sensible validation function and you've got yourself an easy RESTful place to stick your data in.

Categories

Resources