GraphQL field-level validation in AppSync - graphql

I have an AppSync API that's mostly backed by a DynamoDB store. Most of the resolvers are hooked up directly to the DynamoDB sources, not using lambdas.
Some of the fields should have validation constraints, such as length or a regexp. In one particular case I would like to require that a state field contain an ISO 3166-2 value like US-NY. (GraphQL enums values can't contain hyphens, so that isn't an option here.)
Other than replacing some resolvers with lambdas, the only way I can think of to apply these sorts of validation rules is to do it in VTL in the RequestMappingTemplate. That would work, but it would be tedious and likely result in duplicate code. Are there alternatives?

Unfortunately, only way without lambda is VTL , I suggest that instead of writing validation directly inside RequestMappingTemplate, using pipeline resolver.(less duplicated)
Pipeline Resolvers contain one or more Functions which are executed in order.
Functions allow you to write common logic for reuse across multiple Resolvers in your schema. They are attached directly to a data source and like a Unit resolver, contain the same request and response mapping template format.
You can find a good example here.

Related

Will graphql run resolver with additional arguments

If graphql query schema is like this:
user(user_id: Int): User
Will apollo run resolver if in query will be additional (email) argument not defined in query schema?
I want iterate arguments in resolver, but not sure if it possible to pollute them.
P.S. If there is documentation of how apollo parcing arguments, will appreciate.
In GraphQL, a schema defines what fields are available to the client, including what arguments are available for that field and what the types of those arguments are. Any query submitted to a GraphQL service will first be validated before it's executed. If the query includes any extraneous arguments, it will fail validation and won't be executed. This is explained here in the spec:
Formal Specification
For each argument in the document
Let argumentName be the Name of argument.
Let argumentDefinition be the argument definition provided by the parent field or definition named argumentName.
argumentDefinition must exist.
Explanatory Text
Every argument provided to a field or directive must be defined in the set of possible arguments of that field or directive.
For a better idea of how GraphQL works, I would suggest taking at least a cursory look through the spec.

Is it okay for a resolver to have side effects besides resolving the type?

When creating a GraphQL mutation or query, you usually retrieve or save data. But let's assume I would like to send an e-mail when the data is saved or perform some additional side effects.
Is it common practice for resolvers to have these kind of side effects? Since resolvers should only resolve data according to the SOLID principle, right?
If it turns out that the resolver should not have side effects like these, then where would the side effects belong?
Most tutorials and articles online, including the official tutorial of GraphQL itself, don't seem to cover this or take it into account.
Many thanks!
It depends on that resolver is resolving fields of what types.
If it is resolving the fields of the root mutation ,it must involve sides effects as mutation is supposed to modify server-side data. So it is okay to send an email in root mutation field 's resolver.
For the resolver of object type and root query fields , as it is supposed to only retrieving data, it is awkward for me if they have any side effects.

Validate a GraphQL schema against another reference schema

I'm not quite sure the wording I should be searching for on this.
I have a GraphQL schema which wraps a group of services using graphql-link-schema to perform the data resolution on the client side. The schema is intended to be built against a separate reference schema. How can I programmatically validate that my implementation matches the reference?
For bonus points- is it possible to determine whether a schema is a superset of another?
Thanks in advance (:
It's an interesting use case, but it's a bit unclear how validation like that would work. What causes validation to fail? Any differences between the two schemas? Extra types? Extra fields on existing types? Differences in return types? Differences in arguments or argument types?
Depending on your answer to the above questions, though, you may be able to cobble together your own validation function using the utility functions available here. Outside the main findBreakingChanges function, some of the utility functions available in that module:
findRemovedTypes
findTypesThatChangedKind
findFieldsThatChangedTypeOnObjectOrInterfaceTypes
findFieldsThatChangedTypeOnInputObjectTypes
findTypesRemovedFromUnions
findValuesRemovedFromEnums
findArgChanges
findInterfacesRemovedFromObjectTypes
If you have a reference or base schema available, though, rather than validating against it, you might also consider extending it when building the second schema. In doing so, you would effectively guarantee that the second schema matches the first except in whatever ways you intentionally deviate from it (by extending existing types, etc.). You could use extendSchema for relatively simply changes, or something like graphql-tool's mergeSchemas for more complicated changes.

Can GraphQL Queries be named, kind of like stored procedures, and reused?

I'm building a Graphene-Django based GraphQL API. One of my colleagues, who is building an Angular client that will use the API, has asked if there's a way to store frequently used queries somehow on the server-side so that he can just call them by name?
I have not yet encountered such functionality so am not sure if it's even possible.
FYI he is using the Apollo Client so maybe such "named" queries is strictly client-side? Here's a page he referred me to: http://dev.apollodata.com/angular2/cache-updates.html
Robert
Excellent question! I think the thing you are looking for is called "persisted queries." The GraphQL spec only outlines
A Type System for a schema
A formal language for queries
How to validate/execute a query against a schema
Beyond that, it is up to the implementation to make specific optimizations. There are a few ways to do persisted queries, and different ones may be more or less helpful for your project.
Storing Queries as a String
Queries can easily be stored as Strings, and the convention is to use *.gql files to do that. Many editors/IDEs will even have syntax highlighting for this. To consume them later, just URL Encode them, and you're all set! Since these strings are "known" you can whitelist the requests on the server if you choose.
const myQuery = `
{
user {
firstName
lastName
}
}
`
const query = `www.myserver.com/query=${urlEncode(myQuery)}`
Persisted Queries
For a more sophisticated approach, you can take queries that are extracted from your project (either from strings or using a build tool), pre-run them and put the result in a DB. This is what Facebook does. There are plenty of tools out there to help you with this, and the Awesome-GraphQL repo is a good place to start looking.
Resources
Check out this blog for more info on Persisted Queries

validate request input phoenix elixir

I'm struggling to find something in the documentation that seems like it should be there...
In Phoenix I see validation at the point of trying to create an Ecto change set, but I'm not seeing much prior to that, upon validating the actual user input.
I'm not really a fan of exposing my data models across API boundaries, and I would rather just have structs representing the requests and responses, as they are likely very different shapes to my actual data models.
I'd like a way of converting user input to a struct and using some kind of validation framework to determine if the input is valid before I even think about hitting a database.
I've found https://github.com/CargoSense/vex and have gone down the route of converting the input to a struct, and using their validation, but there are a few things that worry me about this approach, namely:
I hear that there are issues with atoms in Elixir, and as structs are basically atom keyed maps, am I going to run into this atom exhaustion issue converting user input to these?
I also have some structs that would have nested structs. I'm currently checking the default value provided. If it's a struct doing some magic, based on the answers here In Elixir how do you initialize a struct with a map variable, to automatically convert a nested map to my nested struct. But again, I'm not sure if this is sensible.
The validations I'm defining in one DSL will be very similar in my Ecto models, and I would rather be using this for both.
Basically, how would you go about validating user input correctly in a Phoenix app. Am I on the right lines, or way off?

Resources