protocol • not only as frontend-to-server protocol • REST, gRPC are more popular but GraphQL is better for me • Several months later - • We decided to build a new product from scratch
=> unnecessary • Network cost is low • It's far more dif fi cult to cache in backend because multiple user's data is mixed • generating static code/types => unnecessary • Ruby is dynamically-typed and duck-typing language • generating codes which work with React, etc => unnecessary
"query(bazId: $ID!) { baz(id: $bazId) { a, b { c, d } } }" def self.execute!(baz_id) data = client.execute(query: QUERY, variables: { bazId: baz_id }) ActiveRecord::Base.transaction do Foo.create!(a: data.baz.a) BarOperation.execute!(data.baz.b) end end end class BarOperation def self.execute!(b) Bar.create!(c: b.c, d: b.d) # more complicated logics... end end
{ a, b { c, d } } }" def self.execute!(baz_id) data = client.execute(query: QUERY, variables: { bazId: baz_id }) ActiveRecord::Base.transaction do Foo.create!(a: data.baz.a) BarOperation.execute!(data.baz.b) end end end class BarOperation def self.execute!(b) Bar.create!(c: b.c, d: b.d) # more complicated logics... end end `FooOperation` class needs to know what fi elds `BarOperation` uses It violates “Single- responsibility principle”
{ baz(id: $bazId) { a ...BarOperationFragment } } #{BarOperation::Fragment} EOS def self.execute!(baz_id) data = client.execute(query: QUERY, variables: { bazId: baz_id }) ActiveRecord::Base.transaction do Foo.create!(a: data.baz.a) BarOperation.execute!(data.baz) end end end class BarOperation FRAGMENT = <<~EOS fragment BarOperationFragment on Baz { b { c, d } } EOS def self.execute!(baz) Bar.create!(c: baz.b.c, d: baz.b.d) # more complicated logics... end end
mock data • no static types • We need to stub for same request in several fi les • e.g. api test (request spec) and unit test • => Please use qsona/webmock-graphql • Sorry time is up 😉