77
Beyond REST: Coursera’s Journey to GraphQL Bryan Kane ! @bryanskane " bryan-coursera

Beyond REST: Coursera’s Journey to GraphQL · Chapter One Site speed issues Chapter Two Intro to GraphQL Chapter Three Migrating to GraphQL Chapter Four Learnings and retrospective

  • Upload
    others

  • View
    8

  • Download
    0

Embed Size (px)

Citation preview

Beyond REST: Coursera’s Journey to GraphQL

Bryan Kane ! @bryanskane " bryan-coursera

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

4

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

5

Load Courses

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

6

Load Instructors

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

7

Load Universities

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

Load University Profile

8

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

9

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

10

Backend Client

APIs

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

11

Discussion

AssetService Emails

Catalog Courservice

LearningHierarchy Recs

Growth

Enterprise

Payment

TranslationsLearning

Items UsersAuthEventing

Backend Client

Discussion

AssetService

Emails

Catalog Courservice

LearningHierarchy

Recs

Growth

Enterprise

Payment

Translations LearningItems

UsersAuthEventing

APIs

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

12

Discu

Asset Email

Catal Cours

Learn Recs

Grow

Enter

Paym

Transl Learn UsersAuthEvent

APIs

Backend Client

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

Catalog

13

partners.v1 instructors.v1

courseGrades.v1

courses.v1

enrollments.v1

enrollments.v2

courseVideos.v1quizzes.v1

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

Catalog

14

partners.v1 instructors.v1

courseGrades.v1

courses.v1

enrollments.v1

enrollments.v2

courseVideos.v1quizzes.v1

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

Catalog

15

partners.v1 instructors.v1

courseGrades.v1

courses.v1

enrollments.v1

enrollments.v2

courseVideos.v1quizzes.v1

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

Catalog

16

partners.v1 instructors.v1

courseGrades.v1

courses.v1

enrollments.v1

enrollments.v2

courseVideos.v1quizzes.v1

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

17

Discussion

AssetService

Emails

Catalog Courservice

LearningHierarchy

Recs

Growth

Enterprise

Payment

Translations LearningItems

UsersAuthEventing

Discu

Asset Email

Catal Cours

Learn Recs

Grow

Enter

Paym

Transl Learn UsersAuthEvent

APIs

Backend Client

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

18

We didn’t break up the monolith —

we just moved it to the clients.

Chapter One Site speed

issues

Chapter Two Intro to GraphQL

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

19

Chapter One Site speed

issues

Chapter Two Intro to GraphQL

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

20

GraphQL is a

query language,

not a library.

Chapter One Site speed

issues

Chapter Two Intro to GraphQL

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

21

query MyCoursesQuery { myCourses(limit: 5, sortBy: RECENT) { name slug instructors { firstName lastName university(filter: VISIBLE_TO_LEARNERS) { name country slug } } } }

Chapter One Site speed

issues

Chapter Two Intro to GraphQL

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

query MyCoursesQuery { myCourses(limit: 5, sortBy: RECENT) { name slug instructors { firstName lastName university(filter: VISIBLE_TO_LEARNERS) { name country slug } } } }

22

Chapter One Site speed

issues

Chapter Two Intro to GraphQL

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

query MyCoursesQuery { myCourses(limit: 5, sortBy: RECENT) { name slug instructors { firstName lastName university(filter: VISIBLE_TO_LEARNERS) { name country slug } } } }

23

Chapter One Site speed

issues

Chapter Two Intro to GraphQL

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

query MyCoursesQuery { myCourses(limit: 5, sortBy: RECENT) { name slug instructors { firstName lastName university(filter: VISIBLE_TO_LEARNERS) { name country slug } } } }

24

Chapter One Site speed

issues

Chapter Two Intro to GraphQL

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

25

query MyCoursesQuery { myCourses(limit: 5, sortBy: RECENT) { name slug instructors { firstName lastName university(filter: VISIBLE_TO_LEARNERS) { name country slug } } } }

Chapter One Site speed

issues

Chapter Two Intro to GraphQL

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

26

{ "myCourses": [ { "name": "Machine Learning", "slug": "machine-learning", "instructors": [ { "firstName": "Andrew", "lastName": "Ng" "university": { "name": "Stanford University", "country": "United States", "slug": "stanford" } }] }] }

Chapter One Site speed

issues

Chapter Two Intro to GraphQL

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

27

query MyCoursesQuery { myCourses(limit: 5, sortBy: RECENT) { name slug instructors { firstName lastName university(filter: VISIBLE_TO_LEARNERS) { name country slug } } } }

{ "myCourses": [{ "name": "Machine Learning", "slug": "machine-learning", "instructors": [{ "firstName": "Andrew", "lastName": "Ng" "university": { "name": "Stanford University", "country": "United States", “slug": "stanford" } }] }] }

Chapter One Site speed

issues

Chapter Two Intro to GraphQL

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

28

Chapter One Site speed

issues

Chapter Two Intro to GraphQL

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

29

query CoursePage { course(slug: "machine-learning") { title description } }

<Course />

Chapter One Site speed

issues

Chapter Two Intro to GraphQL

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

30

query CoursePage { course(slug: "machine-learning") { title description

} }

<Course />

university { name logo }

<University />

Chapter One Site speed

issues

Chapter Two Intro to GraphQL

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

31

query CoursePage { course(slug: "machine-learning") { title description

} }

<Course />

university { name logo }

<University />

instructor { name title }

<Instructor />

Chapter One Site speed

issues

Chapter Two Intro to GraphQL

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

32

query CoursePage { course(slug: machine-learning") { title description

} }

<Course />

university { name logo }

<University />

instructor { name title

}

<Instructor />

profile { photo }

<ProfilePhoto />

Chapter One Site speed

issues

Chapter Two Intro to GraphQL

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

33

All queries are backedby a typed schema

Chapter One Site speed

issues

Chapter Two Intro to GraphQL

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

34

type root { myCourses(limit: Int, sortBy: COURSE_SORT): [Course] }

enum COURSE_SORT { RECENT ENROLL_DATE }

type Course { name: String slug: String instructors: [Instructor] }

type Instructor { firstName: String lastName: String university(filter: VISIBILITY_FILTER): University }

Chapter One Site speed

issues

Chapter Two Intro to GraphQL

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

35

Chapter One Site speed

issues

Chapter Two Intro to GraphQL

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

36

Small, but rapidly growing community

Chapter One Site speed

issues

Chapter Two Intro to GraphQL

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

37

visit graphql.org

for more info

38

Migrating to GraphQL

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

39

Backend

Discussion

AssetService

Emails

Catalog Courservice

LearningHierarchy

Recs

Growth

Enterprise

Payment

Translations LearningItems

UsersAuthEventing

Disc

Jon Em

Cat Cou

Lea Rec

Gro

Ent

Pay

Tra Lea UseAutEve

Client

Discussion

AssetService

Emails

Catalog Courservice

LearningHierarchy

Recs

Growth

Enterprise

Payment

Translations LearningItems

UsersAuthEventing

Disc

Ass Em

Cat Cou

Lea Rec

Gro

Ent

Pay

Tra Lea UseAutEve

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

40

Codebase consistency

Convert REST to GraphQL

Add GraphQL on top of REST

Multiple API formatsOne API format

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

41

Codebase consistency

Convert REST to GraphQL

Add GraphQL on top of REST

Multiple API formatsOne API format

Higher investment Lower investmentTime investment

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

42

Codebase consistency

Convert REST to GraphQL

Add GraphQL on top of REST

Multiple API formatsOne API format

Higher investment Lower investment

More flexible Less flexible

Time investment

Full power of GraphQL

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

43

Codebase consistency

Convert REST to GraphQL

Add GraphQL on top of REST

Multiple API formatsOne API format

Higher investment Lower investment

More flexible Less flexible

Less coordination required

More coordination required

Time investment

Full power of GraphQL

Rollout strategy

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

44

Codebase consistency

Convert REST to GraphQL

Add GraphQL on top of REST

Multiple API formatsOne API format

Higher investment Lower investment

More flexible Less flexible

Less coordination required

More coordination required

Greater schema consistency

Can lead to arbitrary schema formats

Time investment

Full power of GraphQL

Rollout strategy

Schema consistency

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

45

Codebase consistency

Convert REST to GraphQL

Add GraphQL on top of REST

Multiple API formatsOne API format

Higher investment Lower investment

More flexible Less flexible

Less coordination required

More coordination required

Greater schema consistency

Can lead to arbitrary schema formats

Time investment

Full power of GraphQL

Rollout strategy

Schema consistency

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

46

Discuss

Asset Emails

Catalog Course

Learnin Recs

Growth

Enterpr

Payme

Transla Learnin UsersAuthEventin

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

47

Discuss

Asset Emails

Catalog Course

Learnin Recs

Growth

Enterpr

Payme

Transla Learnin UsersAuthEventin

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

CataloCatalog

48

Discuss

Asset Emails

Course

Learnin Recs

Growth

Enterpr

Payme

Transla Learnin UsersAuthEventin

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

CataloCatalog

49

Discuss

Asset Emails

Course

Learnin Recs

Growth

Enterpr

Payme

Transla Learnin UsersAuthEventin

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

1

List of public APIs

2

Endpoints and arguments

3

Model schemas

50

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

51

Discussion

AssetService

Emails

Catalog Courservice

LearningHierarchy

Recs

Growth

Enterprise

Payment

TranslationsLearning

ItemsUsersAuthEventing

Assembler

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

52

Schema Designtype CoursesV1 { id: String slug: String ...more fields }

type CoursesV1Resource { myWatchlist(limit: Int, start: String): CoursesV1Connection bySlug(slug: String, limit: Int, start: String): CoursesV1Connection getAll(limit: Int, start: String): CoursesV1Connection get(id: String!): CoursesV1 multiGet(ids: [String], limit: Int, start: String): CoursesV1Connection }

type CoursesV1Connection { elements: [CoursesV1] paging: ResponsePagination }

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

53

https://www.coursera.org /api/courses.v1 ?q=bySlug &slug=ml &fields=id,name,courseUrl

query CoursePageQuery { CoursesV1Resource { bySlug(slug: "ml") { id name courseUrl } } }

REST to GraphQL

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

54

query CoursePageQuery { CoursesV1Resource { course(limit: 123) { instructor { name university { slug country } } myEnrollments { grade } } } }

Data Relations are Powerful

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

55

Backend APIs are a black box

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

56

Backend APIs are a black box• Joining across APIs is hard

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

57

Backend APIs are a black box• Joining across APIs is hard

• We don’t use relational databases • Most data is stored in Cassandra, a NoSQL database • This requires explicit indexes on data for lookups

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

58

Backend APIs are a black box• Joining across APIs is hard

• We don’t use relational databases • Most data is stored in Cassandra, a NoSQL database • This requires explicit indexes on data for lookups

• We want to keep services as independent as possible

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

59

Two types of relationships

Course Instructor

model Course { id slug instructorIds }

model Instructor { id name }

model A knows about model B

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

60

Course Enrollment

model Course { id slug }

model Enrollment { id userId courseId }

Two types of relationships

model A doesn’t know about model B model B knows about model A

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

These are easy — just fetch the data you need by ID

61

courseAPI.addRelation( "instructors" -> ForwardRelation( resourceName = "instructors.v1", idField = "instructorIds", arguments = Map("includeHidden" -> "true"))

Forward Relationships

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

• Define an endpoint on resource B to lookup by model A • Define in resource A how to look up on resource B

62

courseAPI.addRelation( "enrollment" -> ReverseRelation( resourceName = "enrollments.v1", finderName = "byCourseAndUser", arguments = Map( "courseId" -> "$id", "version" -> "$version"))

Reverse Relationships

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

63

Imperative

courseAPI.addRelation({ course => instructorClient.fetchByCourseId(course.id, course.version) .onComplete { instructors => course.set("instructors", instructors) }.onFailure { course.set("instructors", List.empty) } })

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Four Learnings and retrospective

Chapter Two Intro to GraphQL

64

Imperative

courseAPI.addRelation({ course => instructorClient.fetchByCourseId(course.id, course.version) .onComplete { instructors => course.set("instructors", instructors) }.onFailure { course.set("instructors", List.empty) } })

courseAPI.addRelation( "instructors" -> ReverseRelation( resourceName = "instructors.v1", finderName = "byCourseId", arguments = Map("courseId" -> "$id", "version" -> "$version"))

Declarative

Chapter Four Learnings and retrospective

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Two Intro to GraphQL

65

Chapter Four Learnings and retrospective

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Two Intro to GraphQL

query { CoursesV1Resource { bySlug(slug: "machine-learning") { coursePurchases { transactions { transactionDate expirationDate } } certificates { certificateGrantDate certificateGrade } } offersCertificateForPurchase } EnterpriseProgramsV1Resource { myPrograms { eligibleCourses } } } 66

Actual Query Ideal Query

Chapter Four Learnings and retrospective

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Two Intro to GraphQL

query { CoursesV1Resource { bySlug(slug: "machine-learning") { coursePurchases { transactions { transactionDate expirationDate } } certificates { certificateGrantDate certificateGrade } } offersCertificateForPurchase } EnterpriseProgramsV1Resource { myPrograms { eligibleCourses } } } 67

Actual Query Ideal Query

Chapter Four Learnings and retrospective

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Two Intro to GraphQL

query { CoursesV1Resource { bySlug(slug: "machine-learning") { coursePurchases { transactions { transactionDate expirationDate } } certificates { certificateGrantDate certificateGrade } } offersCertificateForPurchase } EnterpriseProgramsV1Resource { myPrograms { eligibleCourses } } } 68

query { CoursesV1Resource { bySlug(slug: "machine-learning") { shouldShowUpsell } } }

Actual Query Ideal Query

Chapter Four Learnings and retrospective

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Two Intro to GraphQL

69

GraphQL isn't magic

Chapter Four Learnings and retrospective

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Two Intro to GraphQL

70

GraphQL isn't magic

• Don’t let your GraphQL queries become too complex —

move your business logic downstream.

Chapter Four Learnings and retrospective

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Two Intro to GraphQL

71

GraphQL isn't magic

• Don’t let your GraphQL queries become too complex —

move your business logic downstream.

• Build your APIs with GraphQL in mind —

don’t let them live in a silo.

Chapter Four Learnings and retrospective

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Two Intro to GraphQL

72

Popular Courses for JournalistsLearn what it takes to report the news, conduct historical research,understand different viewpoints, and even produce your own intro music.

Chapter Four Learnings and retrospective

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Two Intro to GraphQL

73

Popular Courses for JournalistsLearn what it takes to report the news, conduct historical research,understand different viewpoints, and even produce your own intro music.

query CourseCollectionQuery(slug: String!) { CourseCollectionV1Resource { bySlug(slug: $slug) { title subtitle entries { isEnrolled isOnWishlist course { name photo } } } } }

Chapter Four Learnings and retrospective

Chapter One Site speed

issues

Chapter Three Migrating to

GraphQL

Chapter Two Intro to GraphQL

74

Popular Courses for JournalistsLearn what it takes to report the news, conduct historical research,understand different viewpoints, and even produce your own intro music.

Thanks!Bryan Kane

! @bryanskane " bryan-coursera