200101PRI-Brazil Towards a Sustainable Growth Path-Arminio Fraga (1)
GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can...
Transcript of GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can...
![Page 1: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/1.jpg)
GraphQL in Python and DjangoPatrick Arminio @patrick91
![Page 2: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/2.jpg)
Who am I
● Patrick Arminio
● Backend Engineer @ Verve
● Chairperson at Python Italia
● @patrick91 online
![Page 3: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/3.jpg)
GraphQL?
![Page 4: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/4.jpg)
WEB 1.0
![Page 5: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/5.jpg)
![Page 6: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/6.jpg)
WEB 2.0
![Page 7: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/7.jpg)
![Page 8: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/8.jpg)
REST APIs
![Page 9: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/9.jpg)
While REST APIs are good, they have some shortcomings
![Page 10: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/10.jpg)
Too many API calls
(under-fetching)
![Page 11: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/11.jpg)
http GET /user/1
![Page 12: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/12.jpg)
{
"name": "Patrick",
"friends": [
"/users/2",
"/users/3",
"/users/4"
],
"avatar": "/images/123"
}
![Page 13: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/13.jpg)
http GET /user/2http GET /user/3http GET /user/4
![Page 14: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/14.jpg)
http GET /user_with_friends/1
![Page 15: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/15.jpg)
{
"name": "Patrick",
"friends": [
{ "name": "Fiorella" },
{ "name": "Marco" },
{ "name": "Marta" }
],
"avatar": "/images/123"
}
![Page 16: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/16.jpg)
http GET /user_with_friends/1
![Page 17: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/17.jpg)
http GET /user_with_friends/1http GET /user_with_friends_and_avatar/1
![Page 18: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/18.jpg)
http GET /user_with_friends/1http GET /user_with_friends_and_avatar/1http GET /user_with_avatar/1
![Page 19: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/19.jpg)
http GET /user_with_friends/1http GET /user_with_friends_and_avatar/1http GET /user_with_avatar/1http GET /user_with_small_avatar/1
![Page 20: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/20.jpg)
http GET /user_with_friends/1http GET /user_with_friends_and_avatar/1http GET /user_with_avatar/1http GET /user_with_small_avatar/1http GET /user_with_small_avatar_and_friends/1
![Page 21: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/21.jpg)
http GET /user_with_friends/1http GET /user_with_friends_and_avatar/1http GET /user_with_avatar/1http GET /user_with_small_avatar/1http GET /user_with_small_avatar_and_friends/1http GET /page-1
![Page 22: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/22.jpg)
http GET /user_with_friends/1http GET /user_with_friends_and_avatar/1http GET /user_with_avatar/1http GET /user_with_small_avatar/1http GET /user_with_small_avatar_and_friends/1http GET /page-1http GET /page-2
![Page 23: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/23.jpg)
[...] At the time, we had over 1,000 different REST endpoints at Coursera (and now we have many more) [...]
Source: Courserahttps://dev-blog.apollodata.com/courseras-journey-to-graphql-a5ad3b77f39a
![Page 24: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/24.jpg)
Too much data (over-fetching)
![Page 25: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/25.jpg)
{
"name": "Patrick",
"friends": [{
"name": "Ernesto",
"friends": ["/users/2", "/users/3", "/users/4"],
"avatar": {
"url": "//cdn.x.com/123.jpg",
"width": 400,
"height": 300
}
},
{
"name": "Simone",
"friends": ["/users/2", "/users/3", "/users/4"],
"avatar": {
"url": "//cdn.x.com/123.jpg",
"width": 400,
"height": 300
}
},
{
"name": "Marta",
"friends": ["/users/2", "/users/3", "/users/4"],
"avatar": {
"url": "//cdn.x.com/123.jpg",
"width": 400,
"height": 300
}
}
],
"avatar": {
"url": "//cdn.x.com/123.jpg",
"width": 400,
"height": 300
}
}
![Page 26: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/26.jpg)
![Page 27: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/27.jpg)
REST AND HYPERMEDIA LINKS ARE GREAT, BUT NOT ALWAYS THE BEST CHOICE WHEN BUILDING WEBSITES OR APPS.
![Page 28: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/28.jpg)
Documentation
![Page 29: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/29.jpg)
![Page 30: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/30.jpg)
Can we do better?
![Page 31: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/31.jpg)
We could extend REST, but...
![Page 32: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/32.jpg)
There won’t be a standard way
![Page 33: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/33.jpg)
GraphQL! ✨
![Page 34: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/34.jpg)
GraphQL is a Query Language for APIs.
Source: https://graphql.org/
![Page 35: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/35.jpg)
GraphQL is a specification
![Page 36: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/36.jpg)
Single HTTP endpoint
![Page 37: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/37.jpg)
http POST /graphql
![Page 38: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/38.jpg)
{
user(id: "1") {
name
friends {
name
}
avatar
}
}
![Page 39: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/39.jpg)
{
"user": {
"name": "Patrick",
"friends": [
{ "name": "Fiorella" },
{ "name": "Marco" },
{ "name": "Marta" }
],
"avatar": "/images/123"
}
}
![Page 40: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/40.jpg)
GraphQL is typed
![Page 41: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/41.jpg)
type Query {
user(id: ID!): User
}
type User {
name: String!
friends: [Friend!]!
avatar: String!
}
type Friend {
name: String!
}
![Page 42: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/42.jpg)
type Query {
user(id: ID!): User
}
type User {
name: String!
friends: [Friend!]!
avatar: String!
}
type Friend {
name: String!
}
![Page 43: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/43.jpg)
type Query {
user(id: ID!): User
}
type User {
name: String!
friends: [Friend!]!
avatar: String!
}
type Friend {
name: String!
}
![Page 44: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/44.jpg)
type Query {
user(id: ID!): User
}
type User {
name: String!
friends: [Friend!]!
avatar: String!
}
type Friend {
name: String!
}
![Page 45: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/45.jpg)
type Query {
user(id: ID!): User
}
type User {
name: String!
friends: [Friend!]!
avatar: String!
}
type Friend {
name: String!
}
![Page 46: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/46.jpg)
type Query {
user(id: ID!): User
}
type User {
name: String!
friends: [Friend!]!
avatar: String!
}
type Friend {
name: String!
}
![Page 47: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/47.jpg)
Scalar Types
● Int
● Float
● String
● Boolean
● Any user defined scalars (IE. datetime)
![Page 48: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/48.jpg)
Object Types are the objects defined in your GraphQL
API. They are objects that have fields that can of scalar
types or other object types.
Object Types
![Page 49: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/49.jpg)
Type “modifiers”
● List
● Non-nulls
![Page 50: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/50.jpg)
Why is this important?
![Page 51: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/51.jpg)
Static checking
![Page 52: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/52.jpg)
Documentation and introspection
![Page 53: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/53.jpg)
Let’s see an example
![Page 54: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/54.jpg)
![Page 55: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/55.jpg)
Operations
![Page 56: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/56.jpg)
3 Main operations
Subscription
Allows to subscribe to events, for example when
a new user has been created.
Mutation
Allows you to modify/create data on the server.
But it is not limited to data, can be used to run
anything with side effects.
Query
Allows to request data from the server.
![Page 57: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/57.jpg)
Query (shortcut)
{
user(id: "1") {
name
}
}
![Page 58: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/58.jpg)
Query
query QueryName($id: ID!) {
user(id: $id) {
name
}
}
![Page 59: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/59.jpg)
Mutation
mutation MutationName($input: CreateUserInput!) {
createUser(input: $input) {
ok
}
}
![Page 60: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/60.jpg)
Subscription
subscription SubscriptionName {
onUserCreated {
name
}
}
![Page 61: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/61.jpg)
Intermission
![Page 62: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/62.jpg)
GraphQL in Python
![Page 63: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/63.jpg)
2 libraries
![Page 64: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/64.jpg)
Ariadne
https://github.com/mirumee/ariadne/
● Quite new
● Python 3.5+
● “Closer to GraphQL”
![Page 65: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/65.jpg)
Graphene
https://graphene-python.org/
● Most popular
● Python 2.7+ and Python 3.5+
● Nice abstraction on top of GraphQL
● Support for Django and more frameworks
![Page 66: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/66.jpg)
Let’s start withAriadne
![Page 67: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/67.jpg)
We need a schematype Query {
user(id: ID!): User
}
type User {
name: String!
friends: [Friend!]!
avatar: String!
}
type Friend {
name: String!
}
![Page 68: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/68.jpg)
We need a schematype Query {
user(id: ID!): User
}
type User {
name: String!
friends: [Friend!]!
avatar: String!
}
type Friend {
name: String!
}
![Page 69: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/69.jpg)
We need a schematype Query {
user(id: ID!): User
}
type User {
name: String!
friends: [Friend!]!
avatar: String!
}
type Friend {
name: String!
}
![Page 70: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/70.jpg)
How do we link data to the fields?
![Page 71: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/71.jpg)
Resolvers
![Page 72: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/72.jpg)
Each field on each type is backed by a function called the resolver which is provided by the GraphQL server developer.
![Page 73: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/73.jpg)
A simple resolverdef resolve_user(_, info, id):
return {
"name": "Patrick",
"friends": [
{"name": "Fiorella"},
{"name": "Marco"},
{"name": "Marta"},
],
"avatar": "/images/123",
}
![Page 74: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/74.jpg)
Attaching a resolver to a Typeresolvers = {
"Query": {"user": resolve_user},
"User": {"name": resolve_name},
}
![Page 75: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/75.jpg)
Creating and running the serverserver = GraphQLMiddleware.make_simple_server(
schema,
resolvers
)
server.serve_forever()
![Page 76: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/76.jpg)
Done!
![Page 77: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/77.jpg)
![Page 78: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/78.jpg)
Intermission
![Page 79: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/79.jpg)
Graphene
![Page 80: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/80.jpg)
The schema is defined in Python
![Page 81: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/81.jpg)
Our schematype Friend {
name: String!
}
type User {
name: String!
friends: [Friend!]!
avatar: String!
}
type Query {
user(id: ID!): User
}
![Page 82: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/82.jpg)
Defining types with Graphene - Friendclass FriendType(graphene.ObjectType):
name = graphene.String(required=True)
![Page 83: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/83.jpg)
Types and resolvers live together*
* resolvers can also be external functions
![Page 84: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/84.jpg)
Defining types with Graphene - Userclass UserType(graphene.ObjectType):
name = graphene.String(required=True)
friends = graphene.List(graphene.NonNull(FriendType))
avatar = graphene.String(required=True)
def resolve_friends(self, info):
return [
FriendType(name="Marta"),
FriendType(name="Marco"),
FriendType(name="Fiorella"),
]
![Page 85: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/85.jpg)
Defining types with Graphene - Queryclass Query(graphene.ObjectType):
user = graphene.Field(
UserType,
id=graphene.ID()
)
def resolve_user(self, info, id):
return UserType(
name="Patrick",
avatar="/images/123"
)
![Page 86: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/86.jpg)
Finally, the schemaschema = graphene.Schema(query=Query)
![Page 87: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/87.jpg)
Done!
![Page 88: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/88.jpg)
Django SupportGraphene has support for Django, meaning that:
● Has a built in view
● It can create types from django models
● It can create mutations from Forms and DRF Serializers
● Has support for django filters
![Page 89: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/89.jpg)
What about
![Page 90: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/90.jpg)
Authentication
![Page 91: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/91.jpg)
AuthenticationWhen using GraphQL with HTTPs you have 3 options for
authentication:
● Sessions
● HTTP Headers
● Field arguments
![Page 92: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/92.jpg)
SessionsBasically you rely on the browser sending cookies to your backend
service, this works pretty well with Django.
Good when you an API that works only with your frontend and when
you don’t have a mobile application.
![Page 93: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/93.jpg)
HeadersYou can use headers when you have third party clients accessing
your API or when you have a mobile app.
Usually it is used in combination with JWT tokens.
![Page 94: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/94.jpg)
Field paramsThis might be a good solution when you only have a few fields that
require authentication. It could work like this:
{
myBankStatement(token: "ABC123") {
date
amount
}
}
![Page 95: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/95.jpg)
Security
![Page 96: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/96.jpg)
Quite easy to create “malicious” queries
![Page 97: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/97.jpg)
{
thread(id: "some-id") {
messages(first: 99999) {
thread {
messages(first: 99999) {
thread {
messages(first: 99999) {
thread {
# ...repeat times 10000...
}
}
}
}
}
}
}
![Page 98: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/98.jpg)
Solution for “malicious” queriesTo prevent bad queries to happen we can adopt various solutions:
● Timeouts
● Limits on nested fields
● Query cost
● Static queries
![Page 99: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/99.jpg)
TimeoutsCheck how long a query is taking, if it is taking more than 1 second
you can kill it.
● Prevents huge queries from DOS-ing your server
● Prevents long waiting time
![Page 100: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/100.jpg)
Limit on nested fieldsYou can parse the incoming GraphQL request and deny queries that
are requesting for fields that are too nested. For example you can
only allow for maxing 3 levels of nesting and no more.
Easy solution when you don’t need complex checks.
![Page 101: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/101.jpg)
Query costsThis is useful if you have third party clients and when you also want
to limit their API usage.
The idea is to give each field a cost and calculate the cost of the
query based on the number of fields requested.
This works extremely well with paginated data (where you know how
much data you’re asking for)
![Page 102: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/102.jpg)
Query costs - example queryquery {
viewer {
repositories(first: 50) {
issues(first: 10) {
title
}
}
}
}
![Page 103: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/103.jpg)
Query costs - calculating the cost50 = 50 repositories
+
50 x 10 = 500 repository issues
= 550 total nodes
![Page 104: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/104.jpg)
Static queriesInstead of allowing any query to be ran on your API you could allow
only a predefined list of queries. You’d save those queries on a
database and reference them by ID. So instead of doing a request
passing the query to GraphQL you’d pass only the ID (and the
variables if any).
![Page 105: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/105.jpg)
http POST /graphql?id=123
![Page 106: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/106.jpg)
Static queries● Good to prevent unwanted queries
● Still allows to use all the advantages of GraphQL
● A bit cumbersome to deploy
● If you have third party you need a way for them to declare
queries
● Potentially good for caching (see next slide)
![Page 107: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/107.jpg)
http GET /graphql?id=123
![Page 108: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/108.jpg)
Caching
![Page 109: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/109.jpg)
Client Caching
![Page 110: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/110.jpg)
Network Caching
![Page 111: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/111.jpg)
Application Caching
![Page 112: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/112.jpg)
Additional Things
![Page 113: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/113.jpg)
Arguments and Inputs
![Page 114: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/114.jpg)
{
search(text: "an") {
title
}
}
![Page 115: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/115.jpg)
{
createUser(input: { … }) {
user {
name
}
}
}
![Page 116: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/116.jpg)
Input Types
![Page 117: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/117.jpg)
input CreateUserInput {
name: String!
age: Int
}
![Page 118: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/118.jpg)
Enums
![Page 119: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/119.jpg)
enum Conference {
PYPARIS
PYCONX
PYCONUS
}
![Page 120: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/120.jpg)
Interfaces
![Page 121: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/121.jpg)
interface Character {
id: ID!
name: String!
}
type Human implements Character {
id: ID!
name: String!
friends: [Character]
starships: [Starship]
}
![Page 122: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/122.jpg)
union SearchResult = Human | Droid
{
search(text: "an") {
... on Human {
name
height
}
... on Droid {
name
primaryFunction
}
}
}
![Page 123: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/123.jpg)
Errors
![Page 124: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/124.jpg)
![Page 125: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/125.jpg)
And more
![Page 126: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/126.jpg)
Frontend
![Page 127: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/127.jpg)
Frontend developers benefit a lot from GraphQL, thanks to all the tooling available.
![Page 128: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/128.jpg)
Relay
https://facebook.github.io/relay/
● Made by Facebook
● React Only
![Page 129: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/129.jpg)
Apollo
https://www.apollographql.com/
● Supports many frameworks (React, Vue, etc)
● Big community
● Lots of tooling
![Page 130: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/130.jpg)
Verve is Hiring 🎉Want to work in an amazing company and use Python 3, GraphQL and Django?
https://verve.co/careers/
![Page 131: GraphQL in Python and Django - PyParispyparis.org/static/slides/Patrick+Arminio-1cba4f64.pdfYou can parse the incoming GraphQL request and deny queries that are requesting for fields](https://reader033.fdocuments.us/reader033/viewer/2022052015/602df8b2373a8d5436619ea4/html5/thumbnails/131.jpg)
THANKS!Patrick Arminio
@patrick91