{"id":13499550,"url":"https://github.com/apollographql/reason-apollo","last_synced_at":"2025-03-29T05:31:45.198Z","repository":{"id":27314866,"uuid":"113237516","full_name":"apollographql/reason-apollo","owner":"apollographql","description":"Reason binding for Apollo Client and React Apollo","archived":true,"fork":false,"pushed_at":"2023-05-26T20:17:17.000Z","size":3698,"stargazers_count":549,"open_issues_count":108,"forks_count":108,"subscribers_count":39,"default_branch":"master","last_synced_at":"2024-10-01T06:44:37.660Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Reason","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/apollographql.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-12-05T21:59:17.000Z","updated_at":"2024-09-22T05:15:59.000Z","dependencies_parsed_at":"2024-01-10T19:11:12.619Z","dependency_job_id":null,"html_url":"https://github.com/apollographql/reason-apollo","commit_stats":{"total_commits":387,"total_committers":53,"mean_commits":7.30188679245283,"dds":0.6253229974160206,"last_synced_commit":"00c1071e794872fd6b6eb33e7c75b9b6275aedfd"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apollographql%2Freason-apollo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apollographql%2Freason-apollo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apollographql%2Freason-apollo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apollographql%2Freason-apollo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/apollographql","download_url":"https://codeload.github.com/apollographql/reason-apollo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":222465430,"owners_count":16989012,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T22:00:34.753Z","updated_at":"2024-10-31T18:30:46.072Z","avatar_url":"https://github.com/apollographql.png","language":"Reason","funding_links":[],"categories":["Reason","Libraries","Implementations"],"sub_categories":["ReasonML Libraries","ReasonML"],"readme":"# Archival\nThis repo was archived by the Apollo Security team on 2023-05-26 \n\n\n# Reason-apollo\n\n[![npm version](https://badge.fury.io/js/reason-apollo.svg)](https://badge.fury.io/js/reason-apollo)\n[![Join the community on Spectrum](https://withspectrum.github.io/badge/badge.svg)](https://spectrum.chat/apollo)\n\n\u003e react-apollo with ReasonML\n\n## Install and setup\n\n#### Install\n\n```\nyarn add reason-apollo\n\n# Add graphql_ppx\nyarn add @baransu/graphql_ppx_re --dev\n```\n\n#### bsconfig\n\nAdd `reason-apollo` to your `bs-dependencies` and\n`@baransu/graphql_ppx_re/ppx` to your `ppx-flags`\n\n**bsconfig.json**\n\n```\n\"bs-dependencies\": [\n  \"reason-react\",\n  \"reason-apollo\"\n],\n\"ppx-flags\": [\n  \"@baransu/graphql_ppx_re/ppx\"\n]\n```\n\n#### Send introspection query\n\nThis will generate a `graphql_schema.json` which will be used to safely type your GraphQL queries/mutations.\n\n```\nnpx get-graphql-schema ENDPOINT_URL -j \u003e graphql_schema.json\n```\n\n## Why reason-apollo?\n\nWatch its usage in this video:\n\n[![Watch reason-apollo usage here](https://i.ytimg.com/vi/yMqE37LqRLA/hqdefault.jpg?sqp=-oaymwEZCNACELwBSFXyq4qpAwsIARUAAIhCGAFwAQ==\u0026rs=AOn4CLD9rxIyXtckkxmGAxRn_Uv2mDcXcQ)](https://www.youtube.com/watch?v=yMqE37LqRLA)\n\n# Usage\n\n## Create the Apollo Client\n\n**Client.re**\n\n```reason\n/* Create an InMemoryCache */\nlet inMemoryCache = ApolloInMemoryCache.createInMemoryCache();\n\n/* Create an HTTP Link */\nlet httpLink =\n  ApolloLinks.createHttpLink(~uri=\"http://localhost:3010/graphql\", ());\n\nlet instance =\n  ReasonApollo.createApolloClient(~link=httpLink, ~cache=inMemoryCache, ());\n```\n\n## ApolloProvider\n\n**Index.re**\n\n```reason\n/*\n   Enhance your application with the `ReasonApollo.Provider`\n   passing it your client instance\n */\nReactDOMRe.renderToElementWithId(\n  \u003cReasonApollo.Provider client=Client.instance\u003e\n    \u003cApp /\u003e\n  \u003c/ReasonApollo.Provider\u003e,\n  \"index\",\n);\n```\n\n## Query\n\n**MyQuery.re**\n\n```reason\n/* Create a GraphQL Query by using the graphql_ppx */\nmodule GetUserName = [%graphql\n  {|\n  query getUserName($id: ID!){\n    user(id: $ID) {\n      id\n      device {\n        id\n        brand {\n          id\n          name\n        }\n      }\n    }\n  }\n|}\n];\n\nmodule GetUserNameQuery = ReasonApollo.CreateQuery(GetUserName);\n\n[@react.component]\nlet make = () =\u003e {\n  let userNameQuery = GetUserName.make(~id=\"42\", ());\n  \u003cGetUserNameQuery variables=userNameQuery##variables\u003e\n    ...{({result}) =\u003e\n      switch (result) {\n      | Loading =\u003e \u003cdiv\u003e {ReasonReact.string(\"Loading\")} \u003c/div\u003e\n      | Error(error) =\u003e \u003cdiv\u003e {ReasonReact.string(error##message)} \u003c/div\u003e\n      | Data(response) =\u003e\n        \u003cdiv\u003e\n          {/* Handles a deeply nested optional response */\n           response##user\n           -\u003eBelt.Option.flatMap(user =\u003e user##device)\n           -\u003eBelt.Option.flatMap(device =\u003e device##brand)\n           -\u003eBelt.Option.mapWithDefault(\"\", brand =\u003e brand##name)}\n        \u003c/div\u003e\n      }\n    }\n  \u003c/GetUserNameQuery\u003e;\n};\n\n```\n\n## Mutation\n\n**MyMutation.re**\n\n```reason\nmodule AddUser = [%graphql\n  {|\n  mutation addUser($name: String!) {\n    addUser(name: $name) {\n      id\n      name\n    }\n  }\n|}\n];\n\nmodule AddUserMutation = ReasonApollo.CreateMutation(AddUser);\n\n[[@react.component]\nlet make = () =\u003e {\n  \u003cAddUserMutation\u003e\n    ...{(mutation /* Mutation to call */, _ /* Result of your mutation */) =\u003e {\n      let addNewUserQuery = AddUser.make(~name=\"Bob\", ());\n      \u003cdiv\u003e\n        \u003cbutton\n          onClick={_mouseEvent =\u003e\n            mutation(\n              ~variables=addNewUserQuery##variables,\n              ~refetchQueries=[|\"getAllUsers\"|],\n              (),\n            )\n            |\u003e ignore\n          }\u003e\n          {ReasonReact.string(\"Add User\")}\n        \u003c/button\u003e\n      \u003c/div\u003e;\n    }}\n  \u003c/AddUserMutation\u003e;\n};\n```\n\n## Subscription\n\n**MySubscription.re**\n\n```reason\nmodule UserAdded = [%graphql {|\nsubscription userAdded {\n  userAdded {\n    id\n    name\n  }\n}\n|}];\n\nmodule UserAddedSubscription = ReasonApollo.CreateSubscription(UserAdded);\n\n[@react.component]\nlet make = () =\u003e {\n  \u003cUserAddedSubscription\u003e\n    ...{({result}) =\u003e {\n      switch (result) {\n      | Loading =\u003e \u003cdiv\u003e {ReasonReact.string(\"Loading\")} \u003c/div\u003e\n      | Error(error) =\u003e \u003cdiv\u003e {ReasonReact.string(error##message)} \u003c/div\u003e\n      | Data(_response) =\u003e\n        \u003caudio autoPlay=true\u003e\n          \u003csource src=\"notification.ogg\" type_=\"audio/ogg\" /\u003e\n          \u003csource src=\"notification.mp3\" type_=\"audio/mpeg\" /\u003e\n        \u003c/audio\u003e\n      }\n    }}\n  \u003c/UserAddedSubscription\u003e;\n};\n```\n\n## ApolloConsumer\n\nIf you simply want to have access to the ApolloClient, you can use the `ApolloConsumer`\n\n```reason\n\u003cApolloConsumer\u003e\n  ...{apolloClient =\u003e {/* We have access to the client! */}}\n\u003c/ApolloConsumer\u003e;\n```\n\n## Tips and Tricks\n\n### access deeply nested optional objects\n\nIf for this query\n\n```graphql\nquery {\n  user {\n    device {\n      brand {\n        name\n      }\n    }\n  }\n}\n```\n\nyou end up with that kind of code:\n\n```reason\nlet deviceName =\n  switch (response##user) {\n  | None =\u003e \"\"\n  | Some(user) =\u003e\n    switch (user##device) {\n    | None =\u003e \"\"\n    | Some(device) =\u003e\n      switch (device##brand) {\n      | None =\u003e \"\"\n      | Some(brand) =\u003e brand##name\n      }\n    }\n  };\n\n```\n\n1. Use `Belt`\n\n```reason\nopen Belt.Option;\n\nlet deviceName =\n  response##user\n  -\u003eflatMap(user =\u003e user##device)\n  -\u003eflatMap(device =\u003e device##brand)\n  -\u003emapWithDefault(\"\", brand =\u003e brand##name);\n```\n\n2. Use `@bsRecord`\n\nThe `@bsRecord` modifier is an [extension](https://github.com/reasonml-community/graphql_ppx#record-conversion) of the graphql syntax for BuckleScipt/ReasonML. It allows you to convert a reason object to a reason record and reap the benefits of pattern matching, but you need to defined the record by yourself.\n\n```reason\ntype brand = {\n  name: string\n};\n\ntype device = {\n  brand: option(brand)\n};\n\ntype user = {\n  device: option(device)\n};\n\ntype response = user;\n\nquery {\n  user @bsRecord {\n    device @bsRecord {\n      brand @bsRecord {\n        name\n      }\n    }\n  }\n}\n```\n\nThis time we can pattern match more precisely.\n\n```reason\nlet deviceName =\n  switch (response##user) {\n  | Some({device: Some({brand: {name}})}) =\u003e name\n  | _ =\u003e \"\"\n  };\n\n```\n\n3. Use `get_in_ppx`\n\n`npm install get_in_ppx`  \nand in `bsconfig.json`  \n`\"ppx-flags\": [\"get_in_ppx/ppx\"]`  \nyou can write\n\n```reason\nlet deviceName = response##user#??device#??brand#?name;\n```\n\nThere's a [blogpost](https://jaredforsyth.com/posts/optional-attribute-access-in-reason/) from Jared Forsyth (author of this ppx) for more explanation.\n\n### Use an alias for irregular field names\n\nYou might find yourself consuming an API with field names like `Field`. Currently, reason object field names are required to be camel case. Therefore if you have a request like this:\n\n```reason\n{\n  Object {\n    id\n    title\n  }\n}\n```\n\nYou will attempt to access the response object but it will throw an error:\n\n```reason\nresponse##Object; /* Does not work :( */\n```\n\nInstead, use an `alias` to modify the response:\n\n```reason\n{\n  object: Object {\n    id\n    title\n  }\n}\n```\n\nThen you can access the object like this:\n\n```reason\nresponse##object\n```\n\n### Generic Error and Loading components\n\nYou can create a generic error and Loading component and compose them like this example:\n\n```reason\nmodule QueryView = {\n  [@react.component]\n  let make =\n      (\n        ~result: ReasonApolloTypes.queryResponse('a),\n        ~accessData: 'a =\u003e option('b),\n        ~render: ('b, 'c) =\u003e React.element,\n        ~onLoadMore: ('b, 'unit) =\u003e unit=(_, ()) =\u003e (),\n      ) =\u003e {\n    switch (result) {\n    | Error(error) =\u003e \u003cError /\u003e\n    | Loading =\u003e ReasonReact.null\n    | Data(response) =\u003e\n      switch (accessData(response)) {\n      | Some(data) =\u003e render(data, onLoadMore(data))\n      | _ =\u003e \u003cError error=\"\" /\u003e\n      }\n    };\n  };\n};\n\n```\n\n## FAQ\n\n### I've added the schema file, but my build fails saying it couldn't be found?\n\nIn some cases, it seems like there are some differences between the provided `send-introspection-query`\nand output from tools you might be using to download the schema (such as `apollo-codegen` or `graphql-cli`).\nIf your build is failing, please make sure to try with the provided script. In your project root, run:\n\n```\nnpx get-graphql-schema ENDPOINT_URL -j \u003e graphql_schema.json\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapollographql%2Freason-apollo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapollographql%2Freason-apollo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapollographql%2Freason-apollo/lists"}