Skip to Content

Does WunderGraph's JSON RPC support parameters?

Published: September 09, 2021

The Question#

Nicolas Grilly asked us if WunderGraph's JSON RPC supports parameters.

First of all, thank you Nicolas for asking the question!

JSON RPC#

First of all, we need to understand what JSON RPC means in this context.

WunderGraph automatically persists all GraphQL Operations. That is, you write a query, mutation or subscription and we "save" it on the server (WunderNode).

Depending on the name of the operation, we'll automatically generate an endpoint.

If the Operation is a Query or Subscription, the generated endpoint will require the GET verb. In case of a Mutation, the endpoint will require the verb POST.

The template for the endpoint looks like this:

http://example.com/$api/$main/$OperationName?v={"foo":"bar"}

$api is the name of your API, you're free to register as many APIs as you want on your server (WunderNode). $main each API can have multiple environments, e.g. branches. This allows you to deploy multiple instances of the same API, e.g. one environment per Pull Request, Commit, Branch, etc... $OperationName is the name of your Operation. In case of Nicolas example, the OperationName is TopProducts (case sensitive).

Why JSON RPC?#

Well, we could have named it REST but it would be wrong. A lot of people name APIs REST that are not really RESTful. To avoid lengthy discussions we simply call it JSON-RPC which is quite accurate as we're doing RPC using JSON.

Ok, that explains the name, but why does JSON RPC make so much sense?

If you expose your GraphQL API to the public, this creates a long list of problems you'd have to solve. To list just a few of them:

  • Anybody can introspect your GraphQL Schema, (even if you disable introspection)[https://blog.yeswehack.com/yeswerhackers/how-exploit-graphql-endpoint-bug-bounty/] (omg)
  • Your GraphQL Schema might leak sensitive information
  • You have to protect your GraphQL Server from DDOS attacks
    • complex queries
    • deep nesting
    • batch queries
    • n+1 problems
  • Authentication & Authorization Problems
    • You have to make sure that users cannot "traverse" your GraphQL API in unexpected ways
    • e.g. only users with the Admin role can see Admin nodes
    • can you really prove that your GraphQL API is safe?

Ok, how does JSON RPC help against all this? Well, if you don't expose your GraphQL API your don't expose your GraphQL API, that's it. All Operations will be defined by the developer itself and then persisted on the server (WunderNode). At runtime, users cannot create arbitrary Operations. That's as safe as it can get.

Additionally, we're creating a Middleware to validate the Variables of each operation. At build time, we're generating a JSON-Schema for the variables. At runtime, we're using the Schema to validate all inputs. This way, you can trust that WunderGraph will never send malicious queries to your server.

How to set Parameters / Variables for Operations#

Now onto Nicolas question about parameters.

Let's assume we've enhanced the query slightly with an argument to limit the number of topProducts.

query TopProducts($limit: Int!){
topProducts(limit: $limit){
upc
name
price
}
}

We've added the $limit variable to our query to limit the number of topProducts. The JSON structure for the variables of this query will look like this:

{
"limit": 10
}

So, how can we supply this input to the generated endpoint?

curl http://example.com/api/main/TopProducts?v={"limit":10}

Add the variables JSON as the Query Parameter "v" to the URL

How to use Parameters / Variables with Mutations (POST)#

In case of a Mutation, we'll generate a POST endpoint. Therefore, you can simply send the variables JSON as the POST Body.

One more thing: How to inject claims into an operation#

Let's assume, we're creating an endpoint for the user to create an account. The user must already be authenticated (WunderGraph handles this) but they are allowed to define their name.

Thanks to the @fromClaim directive, you're able to inject claims (name value pairs of user information) into an operation.

mutation CreateUser(
$email: String! @fromClaim(name: EMAIL)
$name: String!
) {
createOneusers(data: {email: $email name: $name}) {
id
name
email
}
}

In this case, the CreateUser mutation will be tagged as "requiresAuthentication". Additionally, the $email variable will be omitted from the JSON Schema. This means, the user is not able to supply the variable themselves. The variable will be injected at runtime from the "email" claim.

The user can only supply the variable $name to the operation.

Happy persisting! =)

Have a Question?

Please reach out via Twitter and mention @wundergraphcom or reach out to us on discord.

Product

Subscribe to our newsletter!

Stay informed when great things happen! Get the latest news about APIs, GraphQL and more straight into your mailbox.

© 2021 WunderGraph