Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ITT 2019 - Nikolas Burk - Boost your API Development with GraphQL & Prisma

ITT 2019 - Nikolas Burk - Boost your API Development with GraphQL & Prisma

Only three years after it was introduced by Facebook, GraphQL has replaced REST as the de-facto standard for API development.
A strongly typed API schema, improved performance and a great open-source ecosystem are just some of the benefits developers get with GraphQL.
This talk introduces the current state of GraphQL as well as best practices for GraphQL server development using Prisma and various tools from the GraphQL ecosystem.

Istanbul Tech Talks

April 02, 2019
Tweet

More Decks by Istanbul Tech Talks

Other Decks in Technology

Transcript

  1. • A query language for APIs (alternative to REST) •

    Language-agnostic on backend and frontend • Developed by Facebook, now led by GraphQL Foundation What is GraphQL?
  2. Benefits of GraphQL ✓ "Query exactly the data you need"

    (in a single request) ✓ Declarative & strongly typed schema ✓ Schema used as cross-team communication tool ✓ Decouples teams ✓ Incrementally adoptable ✓ Rich ecosystem & very active community
  3. query { user(id: “user123”) { name posts { title }

    } } HTTP POST { "data" :{ "user": { "name": "Sarah", "posts": [ { "title": "Join us for GraphQL Conf 2019” }, { "title": "GraphQL is the future of APIs" }, ] } } }
  4. REST • Multiple endpoints • Server decides what data is

    returned GraphQL • Single endpoint • Client decides what data is returned
  5. GraphQL for frontend developers • Declarative data fetching • Colocate

    queries with views (e.g. React components) • Powerful GraphQL clients (caching, realtime, offline, …)
  6. GraphQL for backend developers • GraphQL schema defines API operations

    and data structures • Implementation using resolver functions • Datasource-agnostic: GraphQL for any database or legacy API
  7. API definition: The GraphQL schema Implementation: Resolver functions Server: Network

    (HTTP), Middleware, … 3 parts of a GraphQL server 1 2 3
  8. “Hello World” const Query = queryType({ definition(t) { t.string('hello', {

    args: { name: stringArg() }, resolve: (_, args) => { return `Hello ${args.name}` } }) }, }) const schema = makeSchema({ types: [Query] }) const server = new GraphQLServer({ schema }) server.start(() => console.log(`Running on http://localhost:4000`)) index.ts
  9. “Hello World” const Query = queryType({ definition(t) { t.string('hello', {

    args: { name: stringArg() }, resolve: (_, args) => { return `Hello ${args.name}` } }) }, }) const schema = makeSchema({ types: [Query] }) const server = new GraphQLServer({ schema }) server.start(() => console.log(`Running on http://localhost:4000`)) type Query { hello(name: String!): String! } index.ts schema.graphql (generated)
  10. “Hello World” const Query = queryType({ definition(t) { t.string('hello', {

    args: { name: stringArg() }, resolve: (_, args) => { return `Hello ${args.name}` } }) }, }) const schema = makeSchema({ types: [Query] }) const server = new GraphQLServer({ schema }) server.start(() => console.log(`Running on http://localhost:4000`)) type Query { hello(name: String!): String! } index.ts schema.graphql (generated)
  11. `User` model: Query const User = objectType({ name: 'User', definition(t)

    { t.id('id') t.string('name') } }) const Query = queryType({ definition(t) { t.field('users', { type: 'User', list: true, resolve: () => db.users.findAll() }) }, }) index.ts
  12. const User = objectType({ name: 'User', definition(t) { t.id('id') t.string('name')

    } }) const Query = queryType({ definition(t) { t.field('users', { type: 'User', list: true, resolve: () => db.users.findAll() }) }, }) index.ts `User` model: Query
  13. const User = objectType({ name: 'User', definition(t) { t.id('id') t.string('name')

    } }) const Query = queryType({ definition(t) { t.field('users', { type: 'User', list: true, resolve: () => db.users.findAll() }) }, }) index.ts type User { id: ID! name: String! } type Query { users: [User!]! } schema.graphql (generated) `User` model: Query
  14. const User = objectType({ name: 'User', definition(t) { t.id('id') t.string('name')

    } }) const Mutation = mutationType({ definition(t) { t.field('createUser', { type: 'User', args: { name: stringArg() }, list: true, resolve: (_, args) => db.users.create({name: args.name}) }) }, }) index.ts `User` model: Mutation
  15. const User = objectType({ name: 'User', definition(t) { t.id('id') t.string('name')

    } }) const Mutation = mutationType({ definition(t) { t.field('createUser', { type: 'User', args: { name: stringArg() }, list: true, resolve: (_, args) => db.users.create({name: args.name}) }) }, }) index.ts type User { id: ID! name: String! } type Mutation { createUser(name: String): User! } schema.graphql (generated) `User` model: Mutation
  16. GraphQL resolvers are hard ✗ A lot of CRUD boilerplate

    ✗ Deeply nested queries ✗ Performant database access & N+1 problem ✗ Database transactions ✗ Difficult to achieve full type-safety ✗ Implementing realtime operations
  17. What is Prisma? Database Access (ORM) Type-safe database access with

    the auto-generated Prisma client Migrations Declarative data modeling and schema migrations Admin UI Visual data management with Prisma Admin Prisma replaces traditional ORMs and simplifies database workflows Query Analytics Quickly identify slow data access patterns
  18. Prisma + GraphQL = GraphQL Yoga • GraphQL-native backend framework

    for Node.js • Modern alternative to Ruby on Rails, Spring, Django, … • Features: ✓ Full type-safety (supporting JavaScript & TypeScript) ✓ Deep database integration via Prisma ✓ Powerful CLI (incl. scaffolding, hot-reload dev server, build, ...) ✓ Compatible with GraphQL ecosystem