I am working on a project currently using GrapQL. I am integrating a payment processor, when the user payment is successful, the payment processor sends a POST request to the webhook URL that is meant to point to my server. Now I was wondering how to achieve this, considering that GraphQL exposes just one endpoint, in my case /graphql
. How do I capture the POST request coming in? For better context,
If I was using a REST API, after a successful payment, the webhook is meant to send a POST request with the payment data to /payment/verify
. But how can I achieve this using a GraphQL server, getting the data from the webhook directly to a resolver in my GraphQL server? Thank you, anticipating your response.
2 Answers
Unless the post request sent by the payment processor meets the form of graphql request. The request payload must meet the standard GraphQL AST. Only this way, the GraphQL in your server-side can parse the ASTs, do validation and execution works.
The GraphQL post request form is:
require('isomorphic-fetch');
fetch('https://localhost:4000', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query: `
query {
todos {
edges {
node {
completed
id
text
}
}
}
}`
}),
})
.then(res => res.json())
.then(res => console.log(res.data));
You can create additional routes and endpoints to use as webhooks, but a better way is to extract the webhooks function into an independent service. Connect to the database, execute business logic, and process data.
Your GraphQL API server that only has one endpoint /graphql
is used for the API gateway service. The webhook service is one of the backend services.
1
-
This was the route I followed, I just created an Independent service to accept the POST request and did all necessary business validation there. Thanks for the extra insight on parsing AST's
– thatguyMay 17, 2021 at 9:37
Yes, the short answer is it is not possible.
To receive a webhook, you need a POST HTTP endpoint with an specific body, and graphql used it a different body format that start with "query or mutation" and need it a specific response, for example:
mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
createReview(episode: $ep, review: $review) {
stars
commentary
}
}
And it is not possible make a mapping in easy way.
My advice is create a simple HTTP endpoint to receive the webwook request
For example with NestJS (in this time it’s my favorite BackEnd framework) you can create it.
$ nest g resource web-hook
And you receive…
And you can specify your endpoint like this:
@Controller("webhooks")
export class WebhooksController {
constructor(private readonly webhooksService: WebhooksService) {}
@Post("/order-payment/khipu")
confirmPayment(@Body() confirmPaymentInput: ConfirmPaymentInput) {
return this.webhooksService.confirmPayment(confirmPaymentInput);
}
}
Where the ConfirmPaymentInput is
export class ConfirmPaymentInput {
@IsString()
notification_token: string;
}
And whit that, you can receive it they payload of the webhook.