Should I use only one API to get all data of one screen in GraphQL? - graphql

I'm new to GraphQL and come from RestAPI. When I start to work with GraphQL, I have some confusion about whether I should split API into smaller APIs as worked with RestAPI. Assume, I have a screen that requires to display some following components:
List of books
List of readers.
List of top 5 latest books.
Should I wrap all this information into one API or split them into 3 smaller APIs?

The fundamental aspect of graphQL is that there is never more nor less than a single API endpoint, which is often defined at /graphql/ or /gql/, that can only be accessed via POST. Then you define many queries (effective gets) and mutations (effective posts) that can be called at this endpoint to perform CRUD actions.
Therefore, you should define a single API with three separate queries that return the lists of books, readers, and top 5 latest books.
However, these queries could then be post requests to other RESTful APIs. Although, this is a question with regards to your tech-stack and the degree to which it is decomposed into microservices.

Related

Attribute Based Access Control (ABAC) in a microservices architecture for lists of resources

I am investigating options to build a system to provide "Entity Access Control" across a microservices based architecture to restrict access to certain data based on the requesting user. A full Role Based Access Control (RBAC) system has already been implemented to restrict certain actions (based on API endpoints), however nothing has been implemented to restrict those actions against one data entity over another. Hence a desire for an Attribute Based Access Control (ABAC) system.
Given the requirements of the system to be fit-for-purpose and my own priorities to follow best practices for implementations of security logic to remain in a single location I devised to creation of an externalised "Entity Access Control" API.
The end result of my design was something similar to the following image I have seen floating around (I think from axiomatics.com)
The problem is that the whole thing falls over the moment you start talking about an API that responds with a list of results.
Eg. A /api/customers endpoint on a Customers API that takes in parameters such as a query filter, sort, order, and limit/offset values to facilitate pagination, and returns a list of customers to a front end. How do you then also provide ABAC on each of these entities in a microservices landscape?
Terrible solutions to the above problem tested so far:
Get the first page of results, send all of those to the EAC API, get the responses, drop the ones that are rejected from the response, get more customers from the DB, check those... and repeat until either you get a page of results or run out of customers in the DB. Tested that for 14,000 records (which is absolutely within reason in my situation) would take 30 seconds to get an API response for someone who had zero permission to view any customers.
On every request to the all customers endpoint, a request would be sent to the EAC API for every customer available to the original requesting user. Tested that for 14,000 records the response payload would be over half a megabyte for someone who had permission to view all customers. I could split it into multiple requests, but then you are just balancing payload size with request spam and the performance penalty doesn't go anywhere.
Give up on the ability to view multiple records in a list. This totally breaks the APIs use for customer needs.
Store all the data and logic required to perform the ABAC controls in each API. This is fraught with danger and basically guaranteed to fail in a way that is beyond my risk appetite considering the domain I am working within.
Note: I tested with 14,000 records just because its a benchmark of our current state of data. It is entirely feasible that a single API could serve 100,000 or 1m records, so anything that involves iterating over the whole data set or transferring the whole data set over the wire is entirely unsustainable.
So, here lies the question... How do you implement an externalised ABAC system in a microservices architecture (as per the diagram) whilst also being able to service requests that respond with multiple entities with a query filter, sort, order, and limit/offset values to facilitate pagination.
After dozens of hours of research, it was decided that this is an entirely unsolvable problem and is simply a side effect of microservices (and more importantly, segregated entity storage).
If you want the benefits of a maintainable (as in single piece of externalised infrastructure) entity level attribute access control system, a monolithic approach to entity storage is required. You cannot simultaneously reap the benefits of microservices.

Mechanisms for response aggregation in event sourcing based microservices

When it comes to implementing event sourcing based microservices, one of the main concerns that we've come across is aggregating data for responses. For an example we may have two entities like school and student. One microservice may be responsible for handling school related business logic while another may handle students.
Now if someone makes a query through a REST endpoint and ask for a particular student and they might expect both school and student details, then the only known ways for me are the following.
Use something like service chaining. An example would be an Api-Gateway aggregating a response after making couple of requests to couple of microservices.
Having everything replicated throughout all services. Essentially, data would be duplicated.
Having services calling each other for those extra bit of information. This solution works but hard to scale and goes against basic idea of using event sourcing.
My question is that what other ways are there to do this ?
A better approach can be to create a separate reporting/search service, that aggregates the data from both services. For example implemented using ElasticSearch or SOLR.This now allows the users to do search and queries across multiple services and aggregates.
Sure, it will be eventually consistent, but I doubt that is s a problem. This gives a better separation of concerns and you get a nice search experience for your users at the same time.

Ideal way to use graphql

I am new user for graphql. I am planning to use graphql as a middleware layer where different application will hit the API and get the data they require. But main problem is training different groups as to how to post data and query the data they require. Is is good idea to build a middleware which accepts JSON over REST api and converts it to graphql request. I am thinking of 2 options
1. Build REST middle layer which accepts JSON and convert it to graphql request.
2. Ask user to get comfortable with graphql.
Mixing REST and graphql is never a good idea for a new project, because you will waste your resources for doing the same thing in two different ways and you will have to maintain larger codebase. Providing REST and graphql at the same time may seems like a convenience for your customers but in the long run, it is not. Smaller, well structured and well documented API is always preferable.
If you are going to mix and match different resources or call outside services graphql offers better solution. Graphql provides strong typing, single round trip, query batching, instrospection and better dev tools, versionless API.

Am I misusing GraphQL if I must decompose REST data, then re-aggregate it?

We are considering using GraphQL on top of a REST service (using the
FHIR standard for medical records).
I understand that the pattern with GraphQL is to aggregate the results
of multiple, independent resolvers into the final result. But a
FHIR-compliant REST server offers batch endpoints that already aggregate
data. Sometimes we’ll need à la carte data—a patient’s age or address
only, for example. But quite often, we’ll need most or all of the data
available about a particular patient.
So although we can get that kind of plenary data from a single REST call
that knits together multiple associations, it seems we will need to
fetch it piecewise to do things the GraphQL way.
An optimization could be to eager load and memoize all the associated
data anytime any resolver asks for any data. In some cases this would be
appropriate while in other cases it would be serious overkill. But
discerning when it would be overkill seems impossible given that
resolvers should be independent. Also, it seems bloody-minded to undo
and then redo something that the REST service is already perfectly
capable of doing efficiently.
So—
Is GraphQL the wrong tool when it sits on top of a REST API that can
efficiently aggregate data?
If GraphQL is the right tool in this situation, is eager-loading and
memoization of associated data appropriate?
If eager-loading and memoization is not the right solution, is there
an alternative way to take advantage of the REST service’s ability
to aggregate data?
My question is different from
this
question and
this
question because neither touches on how to take advantage of another
service’s ability to aggregate data.
An alternative approach would be to parse the request inside the resolver for a particular query. The fourth parameter passed to a resolver is an object containing extensive information about the request, including the selection set. You could then await the batched request to your API endpoint based on the requested fields, and finally return the result of the REST call, and let your lower level resolvers handle parsing it into the shape the data was requested in.
Parsing the info object can be a PITA, although there's libraries out there for that, at least in the Node ecosystem.

Performance will be better using CSOM or REST API to retrieve data from 4 lists simultaneously.?

I am developing Sharepoint hosted app, and there is a situation where i need to get the data from 4 lists simultaneously, then use it later on. I am able to do it using CSOM. But performance wise what will be better CSOM or REST API. If rest API is the better approach then how can i do it.?
My approach for SharePoint-hosted add-in is to use
a. REST API when requesting:
Single Element / Single Collection retrieval (single List, single ListColletion, single ListItem, single ListItemCollection, single Field, single FieldCollection etc.)
Large Datasets
Two things to consider when using REST API:
i. I do prefer using sp.RequestExecutor.js to executeQueryAsync over $Ajax calls. Reason #1: developing addins that interacts with other Site Collections or sibling webs. Reason #2: your X-RequestDigest header is resolved natively.
ii. Choose wisely your odata value in the Accept: application/json; odata=? header. odata=verbose is, well, verbose, meaning that it returns A LOT of generally unuseful metadata information that slow down responses. odata=mininalmetadata is a good choice for when you need a single metadatata information. odata=nometadata is what you generally need. Note that the object returned varies. While in verbose mode: obj.body.d.results. For the two other methods, obj.body.value
b. I use JSOM API when I need to:
Request ==at once== more than one List or ListItem, or need to load into the context different elements.
Batch updates
References:
https://blogs.msdn.microsoft.com/brian_farnhill/2014/03/11/approaches-to-optimising-sharepoint-client-side-communication/
http://www.andrewconnell.com/blog/sharepoint-2013-csom-vs.-rest-...-my-preference-and-why
http://blog.mannsoftware.com/?p=1521
https://blogs.office.com/2014/08/13/json-light-support-rest-sharepoint-api-released/
http://www.odata.org/documentation/odata-version-2-0/overview/
https://msdn.microsoft.com/en-us/library/office/dn168907.aspx
http://www.vrdmn.com/2013/07/batch-operations-using-javascript.html
I invite you to read this article :
http://blog.mannsoftware.com/?p=1521
In my understanding, REST shows better performance. In time response time, it's about 30% shorter.
And how to dot it ?
With Ajax, it's quite easy. Here is an example which show how to use it :
http://blogs.msdn.com/b/nickpinheiro/archive/2015/01/30/build-a-sharepoint-hosted-app-to-access-list-data-in-your-host-web-using-the-rest-api-in-10-easy-steps.aspx

Resources