So I've been building my new app with GraphQL. It works great with modifying my apps models. But I find there's a serious hole in the way GraphQL works that REST API's handle better. For example, here's my use case:
When a form on my frontend is submitted, it creates a mutation: createFoo.
This alone works great. It creates a new Foo object in my database. But now I have this additional use case:
When the form is submitted, I want to hit a service that not only creates a Foo object in my database, but I also want to hit a third party API (some service I'm using) notifying me of the new creation.
How do I achieve this? With a REST API I would simply add that additional task as part of the API endpoint. With GraphQL there is no concept of a service layer that does other business logic. Should I do this in the mutation? It seems like a weird side effect to add some additional business logic to a mutation that creates an object..How are these things thought of in GraphQL world?
Related
Ok, As per my understanding we use middleware in redux for all the async calls now from Apollo documentation we can directly use queries and mutation inside our component.
I personally thought that writing all the business logic in a separate place using middleware is more intuitive as it helps in keeping business logic away from UI (where the data interchange could take place using redux)
Is there any way to keep my business logic separate using redux middleware with GraphQL rather than mixing it in my UI ?
Just like fetch or axios in redux-logic's create-logger.
Is there any way to keep my business logic separate using redux middleware with GraphQL rather than mixing it in my UI ?
You can achieve it by using apollo-fetch with redux-saga which is a Redux middleware.
When there is a need to fetch data, dispatch a simple sync Redux action. It gets intercepted by redux-saga that can use Apollo to fetch the data asynchronously, can perform other async actions in response if needed and then dispatch one or several sync actions to Redux store.
The business logic can then be split between async redux-saga functions called 'sagas' that could trigger other sagas to accomodate more complex logic and finally dispatch action(s) to Redux which remains the main 'source of truth' in your application.
Given that my team is already using graph/Apollo Client, we've recently been moving away from using Redux, and rather opting for Apollo Client's built in solution to manage local state. As noted in its docs:
Apollo Client (>= 2.5) has built-in local state handling capabilities
that allow you to store your local data inside the Apollo cache
alongside your remote data. To access your local data, just query it
with GraphQL. You can even request local and server data within the
same query!
More specifically, using the #client directive, you flag that you would like to fetch the field data locally using either a client-side resolver to execute local queries or mutations, or from the cache. You can take a look at the docs here. The ability to use this single tool has simplified our local state management. More importantly, this solution could meet your request to have more seperation between UI and business logic, as that logic should largely be encapsulated in your client-side resolvers, which can handle async requests, including requests over the network.
I'm trying to figure out how I might be able to adopt Apollo in my React Native project compared to RXJS & Redux.
One of the special things about this app is that data mutations are not done through a traditional API but through Blockchain based transactions. Therefore I cannot simply call mutate in Apollo and expect it to eventually mutate something on the database as it's gonna go to a completely different several using a completely different library.
Would it be possible to have some kind of middleware which intercepted a mutation request and redirected it to another async library to get the job done? I'm wondering if apollo-link might be the way to do it.
My idea is to create a microservice approch with graphql and serverless.
I'am thinking about creating a service for every table in the dynamodb and then create a apigateway service, and in the apigateway service use graphql-tool to stitch the schemas together.
This work pretty good and I'am satisfied.
But now I want to add authorization to my graphql queries and mutations.
I have added a custom autherizer in the apigateway that resolves the JWT token from the client and sends it to the graphql context with the userId
But now I want to add authorization to my resolvers.
What is the best approach for this?
I want it to be as moduler as possible and and best (i think) is to add the authorization in the apigatway service so my other service stay clean. But I don't know how?
Any ideas?
You may want to look into AppSync from AWS. It will handle a lot of this for you; authorizers, querying DyanmoDB, etc.
I've built Lambda APIs using Apollo GraphQL and exposed them through API Gateway. I then used Apollo's schema stitching to connect them together. There's one really important caveat here: It's slooow. There's already a speed penalty with API Gateway and while it's acceptable, imagine jumping through multiple gateways before returning a response to a user. You can cache the schema which helps a bit. Your tolerance will depend on your app and UX of course. Maybe it's just fine - only you (or your users) can answer that.
That note aside, the way I handled auth was to accept an Authorization header and make a check manually. I did not use any custom authorizers from API Gateway. I was not using Cognito for this so it talked to another service. This all happened before the resolvers. Why are you looking to do the authorization in resolvers? Are there only some that you wish to protect? Access control?
It may not be best to add the custom authorizers to API Gateway in this case...Because you're talking about performing this action at the resolver level in the code.
GraphQL has one POST endpoint for everything. So this is not going to help with configuring API Gateway auth per resource. That means you're now beyond API Gateway and into the invocation of your Lambda anyway. You didn't prevent the invocation so you're being billed and running code now.
So you might as well write your custom logic to authenticate. If you're using Cognito then there is an SDK to help you out. Or take a look at AppSync.
I'm working on a web application that need to expose Json API for external apps and I'm planning to do an API centric architecture.
So basicly, the app will juste contains view/controllers for the web interface. the controllers will use Route::dispatch to create a request to the api part of the site (another controller in a package, but in the same laravel installation), then parse the result, and create view accordingly.
So I'm wondering what are the drawbacks, performance wise, of using this sort of architecture?
If each controller is writing the logic to internally dispatch another request then I'd consider abstracting that away from the controller and in to your own dispatcher. I doubt there would be a huge performance overhead. The application (as far as I know) doesn't get booted twice so you don't have to worry about that.
The only thing you need to be aware of is the input for the main request being used. Something you should take into account inside your dispatcher. Refer to this answer for more information.
You can also read more on consuming your own API.
I wanted to start using breeze js with an existing application. This application already has existing service that expose domain objects that are mapped from entity framework data object.
I wanted to expose these domain objects meta data to breeze so i could use it to track these entities on the client side and save changes. When these changes are saved from breeze I would then work out server side what needed to be done to persist these changes to my data objects.
I've looked at the EF context provider supplied in the breeze samples and was wondering what would be required to create a new context provider that would wrap my domain model ( not DBContext) exposing its metadata and also implement custom saving logic?
Has anyone done this already? Is there pipeline for breeze I've had a look on the user voice site and it looks like Extensible saveOptions and queryOptions are already under review but there is not much detail.
There is a ToDo-NoEF sample provided in the samples zip found here. It shows how to communicate with an arbitrary IQueryable on the server. Is this what you were looking for?