{"action":"created","issue":{"url":"https://api.github.com/repos/apollographql/apollo-server/issues/1683","repository_url":"https://api.github.com/repos/apollographql/apollo-server","labels_url":"https://api.github.com/repos/apollographql/apollo-server/issues/1683/labels{/name}","comments_url":"https://api.github.com/repos/apollographql/apollo-server/issues/1683/comments","events_url":"https://api.github.com/repos/apollographql/apollo-server/issues/1683/events","html_url":"https://github.com/apollographql/apollo-server/pull/1683","id":361004511,"node_id":"MDExOlB1bGxSZXF1ZXN0MjE2MDg1MjU0","number":1683,"title":"Allow willResolveField's handlers to modify the result","user":{"login":"baer","id":940667,"node_id":"MDQ6VXNlcjk0MDY2Nw==","avatar_url":"https://avatars2.githubusercontent.com/u/940667?v=4","gravatar_id":"","url":"https://api.github.com/users/baer","html_url":"https://github.com/baer","followers_url":"https://api.github.com/users/baer/followers","following_url":"https://api.github.com/users/baer/following{/other_user}","gists_url":"https://api.github.com/users/baer/gists{/gist_id}","starred_url":"https://api.github.com/users/baer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/baer/subscriptions","organizations_url":"https://api.github.com/users/baer/orgs","repos_url":"https://api.github.com/users/baer/repos","events_url":"https://api.github.com/users/baer/events{/privacy}","received_events_url":"https://api.github.com/users/baer/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":2,"created_at":"2018-09-17T19:14:07Z","updated_at":"2018-11-14T23:02:42Z","closed_at":null,"author_association":"NONE","pull_request":{"url":"https://api.github.com/repos/apollographql/apollo-server/pulls/1683","html_url":"https://github.com/apollographql/apollo-server/pull/1683","diff_url":"https://github.com/apollographql/apollo-server/pull/1683.diff","patch_url":"https://github.com/apollographql/apollo-server/pull/1683.patch"},"body":"👋 What's up team Apollo?! Long time no see :). I'd like to propose a change to the Extensions API. This code **IS A POC** and **HAS NOT BEEN TESTED YET** but I'll gladly help to harden and test it if you are interested in accepting the PR.\r\n\r\n## Problem:\r\nCurrently, there the `graphql-extension` API does not provide a way to modify the response as it passes through `willResolveField`\r\n\r\n## A specific use case:\r\nAutomate setting cacheHints in Apollo from the TTLs specific to your data sources. For example, if your model returns data in the form: `{ __isUsingModelCache__: true, result, ttl }` you could easily write an extension to read that information. Below is a simplified example of how that would look:\r\n\r\n```javascript\r\nconst myResolver = (obj, args, context) => context.models.customer.getById(args.id);\r\n```\r\n\r\n```javascript\r\nclass CacheHintExtension extends GraphQLExtension {\r\n  constructor() {\r\n    super();\r\n  }\r\n\r\n  willResolveField(obj, args, context, info) {\r\n    if (isNil(obj) || !obj.__isUsingModelCache__) {\r\n      return obj;\r\n    }\r\n\r\n    // Set cache hints\r\n    info.cacheControl.setCacheHint({ maxAge: obj.ttl });    \r\n\r\n    // Unwrap data\r\n    return obj.data;\r\n  }\r\n}\r\n```\r\n\r\nNote: because of how `graphql-extensions` is written, you would need to return a callback and not a value. The above is only meant to illustrate the point."},"comment":{"url":"https://api.github.com/repos/apollographql/apollo-server/issues/comments/438851924","html_url":"https://github.com/apollographql/apollo-server/pull/1683#issuecomment-438851924","issue_url":"https://api.github.com/repos/apollographql/apollo-server/issues/1683","id":438851924,"node_id":"MDEyOklzc3VlQ29tbWVudDQzODg1MTkyNA==","user":{"login":"baer","id":940667,"node_id":"MDQ6VXNlcjk0MDY2Nw==","avatar_url":"https://avatars2.githubusercontent.com/u/940667?v=4","gravatar_id":"","url":"https://api.github.com/users/baer","html_url":"https://github.com/baer","followers_url":"https://api.github.com/users/baer/followers","following_url":"https://api.github.com/users/baer/following{/other_user}","gists_url":"https://api.github.com/users/baer/gists{/gist_id}","starred_url":"https://api.github.com/users/baer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/baer/subscriptions","organizations_url":"https://api.github.com/users/baer/orgs","repos_url":"https://api.github.com/users/baer/repos","events_url":"https://api.github.com/users/baer/events{/privacy}","received_events_url":"https://api.github.com/users/baer/received_events","type":"User","site_admin":false},"created_at":"2018-11-14T23:02:42Z","updated_at":"2018-11-14T23:02:42Z","author_association":"NONE","body":"Hey @martijnwalraven, no prob. I assume you were busy launching your new product at this years summit. Congrats! I'm definitely still interested in working on this - I spent more time than I'd like to admit trying to get my cache hints and data-fetching TTLs to line up and I'm not thrilled with where that landed. I'd love to talk details sometime but just based on your comments, a few things to consider:\r\n\r\nThe `RESTDataSource`, as it's written, solves a somewhat constrained problem. To use it, you have to:\r\n* fetch your data over HTTP\r\n* Be okay with calling all traffic over HTTP REST even if you're fetching using gRPC, another GraphQL server, a Google Docs some other integration.\r\n* Not wanting to use batching (yes, you often shouldn't with HTTP, but there are plenty of exceptions)\r\n\r\nThe biggest gap here is those of us who connect GraphQL resolvers directly to a Database OR those that talk via a binary protocol like Protobuf/Cap n' Proto. Yes, Prisma is an option, but it only supports a [tiny subset](https://github.com/prisma/prisma#database-connectors) (as of today) of the available databases out there so there. Even if you are running MySQL or PostgreSQL, you may not want to or be able to use Prisma. \r\n\r\nIn our case, specifically, some data comes through a REST API, but we fetch other data from a Database and still more from hosted content like Airtable and MicrosoftOffice which requires some special fuckery :). Ultimately, this forced us to create our own Model object that is similar to but not exactly the `RESTDataSource`.\r\n\r\nI'd love to either work towards a general solution like the `graphql-extension` was, or to make it easier to define your own DataSource (I know there is a bit of code out there, but everything seems a bit alpha) and solve it at the base DataSource level rather than in the RESTDataSource specifically.\r\n\r\nAlso, I don't see a problem with returning a TTL in the result. All GraphQL implementations return `{ data: {...}, errors: [...]}` and there are tons of regular APIs that have chosen to do similar things since some consumers freak out on non-200 HTTP status codes.\r\n\r\nWhat's the Proxy idea?"}}
{"actor":{"display_login":"baer"}}