Apollo

Apollo

Apollo is a GraphQL client and cache for JavaScript, iOS (Swift) and Android.

Reason Apollo: ReasonML Binding for Apollo Client

Reason-apollo

react-apollo with ReasonML

Install and setup

Install

yarn add reason-apollo

# Add graphql_ppx
yarn add @baransu/graphql_ppx_re --dev

bsconfig

Add reason-apollo to your bs-dependencies and @baransu/graphql_ppx_re/ppx to your ppx-flags

bsconfig.json

"bs-dependencies": [
  "reason-react",
  "reason-apollo"
],
"ppx-flags": [
  "@baransu/graphql_ppx_re/ppx"
]

Send introspection query

This will generate a graphql_schema.json which will be used to safely type your GraphQL queries/mutations.

npx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json

Why reason-apollo?

Watch its usage in this video:

Watch reason-apollo usage here

Usage

Create the Apollo Client

Client.re

/* Create an InMemoryCache */
let inMemoryCache = ApolloInMemoryCache.createInMemoryCache();

/* Create an HTTP Link */
let httpLink =
  ApolloLinks.createHttpLink(~uri="http://localhost:3010/graphql", ());

let instance =
  ReasonApollo.createApolloClient(~link=httpLink, ~cache=inMemoryCache, ());

ApolloProvider

Index.re

/*
   Enhance your application with the `ReasonApollo.Provider`
   passing it your client instance
 */
ReactDOMRe.renderToElementWithId(
  <ReasonApollo.Provider client=Client.instance>
    <App />
  </ReasonApollo.Provider>,
  "index",
);

Query

MyQuery.re

/* Create a GraphQL Query by using the graphql_ppx */
module GetUserName = [%graphql
  {|
  query getUserName($id: ID!){
    user(id: $ID) {
      id
      device {
        id
        brand {
          id
          name
        }
      }
    }
  }
|}
];

module GetUserNameQuery = ReasonApollo.CreateQuery(GetUserName);

[@react.component]
let make = () => {
  let userNameQuery = GetUserName.make(~id="42", ());
  <GetUserNameQuery variables=userNameQuery##variables>
    ...{({result}) =>
      switch (result) {
      | Loading => <div> {ReasonReact.string("Loading")} </div>
      | Error(error) => <div> {ReasonReact.string(error##message)} </div>
      | Data(response) =>
        <div>
          {/* Handles a deeply nested optional response */
           response##user
           ->Belt.Option.flatMap(user => user##device)
           ->Belt.Option.flatMap(device => device##brand)
           ->Belt.Option.mapWithDefault("", brand => brand##name)}
        </div>
      }
    }
  </GetUserNameQuery>;
};

Mutation

MyMutation.re

module AddUser = [%graphql
  {|
  mutation addUser($name: String!) {
    addUser(name: $name) {
      id
      name
    }
  }
|}
];

module AddUserMutation = ReasonApollo.CreateMutation(AddUser);

[[@react.component]
let make = () => {
  <AddUserMutation>
    ...{(mutation /* Mutation to call */, _ /* Result of your mutation */) => {
      let addNewUserQuery = AddUser.make(~name="Bob", ());
      <div>
        <button
          onClick={_mouseEvent =>
            mutation(
              ~variables=addNewUserQuery##variables,
              ~refetchQueries=[|"getAllUsers"|],
              (),
            )
            |> ignore
          }>
          {ReasonReact.string("Add User")}
        </button>
      </div>;
    }}
  </AddUserMutation>;
};

Subscription

MySubscription.re

module UserAdded = [%graphql {|
subscription userAdded {
  userAdded {
    id
    name
  }
}
|}];

module UserAddedSubscription = ReasonApollo.CreateSubscription(UserAdded);

[@react.component]
let make = () => {
  <UserAddedSubscription>
    ...{({result}) => {
      switch (result) {
      | Loading => <div> {ReasonReact.string("Loading")} </div>
      | Error(error) => <div> {ReasonReact.string(error##message)} </div>
      | Data(_response) =>
        <audio autoPlay=true>
          <source src="notification.ogg" type_="audio/ogg" />
          <source src="notification.mp3" type_="audio/mpeg" />
        </audio>
      }
    }}
  </UserAddedSubscription>;
};

ApolloConsumer

If you simply want to have access to the ApolloClient, you can use the ApolloConsumer

<ApolloConsumer>
  ...{apolloClient => {/* We have access to the client! */}}
</ApolloConsumer>;

Tips and Tricks

access deeply nested optional objects

If for this query

query {
  user {
    device {
      brand {
        name
      }
    }
  }
}

you end up with that kind of code:

let deviceName =
  switch (response##user) {
  | None => ""
  | Some(user) =>
    switch (user##device) {
    | None => ""
    | Some(device) =>
      switch (device##brand) {
      | None => ""
      | Some(brand) => brand##name
      }
    }
  };
  1. Use Belt
open Belt.Option;

let deviceName =
  response##user
  ->flatMap(user => user##device)
  ->flatMap(device => device##brand)
  ->mapWithDefault("", brand => brand##name);
  1. Use @bsRecord

The @bsRecord modifier is an extension 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.

type brand = {
  name: string
};

type device = {
  brand: option(brand)
};

type user = {
  device: option(device)
};

type response = user;

query {
  user @bsRecord {
    device @bsRecord {
      brand @bsRecord {
        name
      }
    }
  }
}

This time we can pattern match more precisely.

let deviceName =
  switch (response##user) {
  | Some({device: Some({brand: {name}})}) => name
  | _ => ""
  };
  1. Use get_in_ppx

npm install get_in_ppx
and in bsconfig.json
"ppx-flags": ["get_in_ppx/ppx"]
you can write

let deviceName = response##user#??device#??brand#?name;

There's a blogpost from Jared Forsyth (author of this ppx) for more explanation.

Use an alias for irregular field names

You 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:

{
  Object {
    id
    title
  }
}

You will attempt to access the response object but it will throw an error:

response##Object; /* Does not work :( */

Instead, use an alias to modify the response:

{
  object: Object {
    id
    title
  }
}

Then you can access the object like this:

response##object

Generic Error and Loading components

You can create a generic error and Loading component and compose them like this example:

module QueryView = {
  [@react.component]
  let make =
      (
        ~result: ReasonApolloTypes.queryResponse('a),
        ~accessData: 'a => option('b),
        ~render: ('b, 'c) => React.element,
        ~onLoadMore: ('b, 'unit) => unit=(_, ()) => (),
      ) => {
    switch (result) {
    | Error(error) => <Error />
    | Loading => ReasonReact.null
    | Data(response) =>
      switch (accessData(response)) {
      | Some(data) => render(data, onLoadMore(data))
      | _ => <Error error="" />
      }
    };
  };
};

FAQ

I've added the schema file, but my build fails saying it couldn't be found?

In some cases, it seems like there are some differences between the provided send-introspection-query and output from tools you might be using to download the schema (such as apollo-codegen or graphql-cli). If your build is failing, please make sure to try with the provided script. In your project root, run:

npx get-graphql-schema ENDPOINT_URL -j > graphql_schema.json

Author: apollographql
Source Code: https://github.com/apollographql/reason-apollo
License: MIT License

#apollo #react 

Reason Apollo: ReasonML Binding for Apollo Client

Apollo Client Devtools: Apollo Client Browser Developer Tools.

Apollo Client Browser Devtools 

This repository contains the Apollo Client Browser Devtools extension for Chrome & Firefox.

Features

The Apollo Client Browser Devtools appear as an "Apollo" tab in your web browser inspector, alongside other tabs like "Elements" and "Console". The devtools currently have four main features:

  • GraphiQL: Send queries to your server through your web applications configured Apollo Client instance, or query the Apollo Client cache to see what data is loaded.
  • Watched query inspector: View active queries, variables, cached results, and re-run individual queries.
  • Mutation inspector: View fired mutations, variables, and re-run individual mutations.
  • Cache inspector: Visualize the Apollo Client cache and search through it by field names and/or values.

Apollo Client Browser Devtools

Installation

You can install the extension via Firefox Browser Add-ons or the Chrome Webstore. If you want to install a local version of the extension instead, skip ahead to the Developing section.

Configuration

While your application is in dev mode, the devtools will appear as an "Apollo" tab in your web browser inspector. To enable the devtools for your application in production, pass connectToDevTools: true to the ApolloClient constructor in your application. Pass connectToDevTools: false if want to manually disable this functionality.

The "Apollo" tab will appear in your web browser inspector if a global window.__APOLLO_CLIENT__ object exists in your application. Apollo Client adds this hook to the window automatically unless process.env.NODE_ENV === 'production'. If you would like to use the devtools in production, manually attach your Apollo Client instance to window.__APOLLO_CLIENT__ or pass connectToDevTools: true to the constructor.

If you are seeing the "Apollo" tab but are still having issues, skip ahead to the Debugging section.

Developing

Installation

After cloning this repo, install the required packages:

cd apollo-client-devtools
npm install

Running the sample application

We provide a sample application to run when developing and testing the extension. To run it, install the required dependencies for both the client and server:

npm run install:dev

Then start the application:

npm run start:dev

Navigate to localhost:3000 to view the application. To view the API schema, navigate to localhost:4000.

Development with web-ext & WebExtWebpackPlugin

For cross-browser development, we rely on the web-ext command line tool and a modified version of the WebExtWebpackPlugin that hooks into the build process.

To develop with Firefox, run the following command:

npm run firefox

For Chrome, run the following command:

npm run chrome

Running either of these commands will:

  • Build and bundle the extension and application
  • Use webpack --watch to watch source files for changes
  • Install the extension in the browser
  • Open the targeted browser window to localhost:3000 (the sample application)
  • Rebuild and reload the extension when the source files are changed

Note that even though the extension is rebuilt and reloaded, a hard refresh is still required. Hot reloading is not an option for web extensions.

Development defaults

Defaults can be found and modified in the WebExtPlugin. You might want to do so if you'd like the targeted browser to open to a different address or to turn on lintOnBuild.

Tests

We use Jest and the React Testing Library to write and run our tests.

To run tests for both src and development, run the following command:

npm run test

You can also run with --watch to watch and re-run tests automatically:

npm run test:watch

Folder structure

There are two main pieces of the Apollo Client Browser Devtools: the extension itself and a React application. The extension is the code that communicates with the browser. It allows us to search an inspected window for an instance of Apollo Client and to create the Apollo tab in the browser's devtools panel. The React application powers the experience in the devtools panel.

The devtools folder structure mirrors this architecture. The source code for the extension can be found in src/extension. The React application code can be found in src/application.

For builds, we use the build folder. After a build, all of the files needed to run the devtools can be found here. If these files are bundled for development, source maps are provided. When these files are bundled for production, source maps are not provided and the code is minified. We use the dist folder for distributable zip files.

Application Structure

The Apollo Client Devtools project is split up by Screens. In the navigation of the Apollo Client Devtools you can select from Explorer, Queries, Mutations and Cache. Each of these Screens has their own React component and is wrapped in a Layout component.

Explorer:

The Explorer is an Embedded iframe that renders Apollo Studio's Explorer. The Explorer accepts post messages from the dev tools to populate the schema and to communicate network requests and responses. All network requests are done in this app via the parent page's Apollo Client instance. Documentation for all of the configurable properties of the Embedded Explorer can be found in the studio docs.

Communication between client & tab

hook.ts is where we hook into the Apollo Client instance of the parent page and execute operations. In initializeHook we set up a communication between the client page and the Apollo Client Devtools tab via an instance of Relay.ts using postMessage. The hook sends the tab information from the parent page, such as the queries, mutations & the cache info on this page (from the Apollo Client instance), responses that come back from Devtools-triggered network requests, and when the page is reloading.

tabRelay.ts is injected into each tab via script tag. Any communication that needs to go from the client to the Apollo Client Devtools need to be forwarded in tabRelay.ts.

devtools.ts is the file where all Apollo Client Devtools communication happens. In this file, network communications for executed operations are forwarded to the Explorer. This is also the file where incoming client messages about the tab state are handled & acted on. Any communication that needs to go from the Apollo Client Devtools to the client needs to be forwarded in devtools.ts.

explorerRelay.ts is a file with a bunch of exported functions that are specific to the Explorer network communications for executed operations. devtools.ts uses the functions as callbacks for its incoming messages, and Explorer.tsx uses the functions to dispatch network requests & accept responses to display in the embedded Explorer.

Explorer network communication

When requests are triggered by the user from Explorer, sendExplorerRequest in explorerRelay.ts dispatches an EXPLORER_REQUEST event which is picked up in devtools.ts and forwarded to the client. In hook.ts the EXPLORER_REQUEST message is listened for, and an operation is executed. When a response for this network request is recieved by the client, EXPLORER_RESPONSE is sent to the tab by the client in hook.ts. This message is forwarded in tabRelay.ts to the devtools, which calls sendResponseToExplorer which is picked up by receiveExplorerResponses called in Explorer.tsx.

Debugging

If there is an error in the devtools panel, you can inspect it just like you would inspect a normal webpage.

In Chrome, detach the inspector console from the window (if it's not already detached) by clicking the button with three vertical dots in the upper right corner of the console and selecting the detach option. With the detached console in focus, press opt-cmd-I again to open an inspector for the detached console (inspector inception). In this new inspector you will be able to inspect elements in the first inspector, including the devtools panel.

In Firefox, go to about:debugging, click on This Firefox, find the Apollo Devtool extension and click Inspect.

If you are using Apollo Client 2.0, make sure you are using at least version 2.0.5 of the devtools.

If you are using Apollo Client 3.0, make sure you are using at least version 2.3.5 of the devtools.

If you're seeing an error that's being caused by the devtools, please open an issue on this repository with a detailed explanation of the problem and steps that we can take to replicate the error.

Publishing

Release process, for those with permission:

  1. Verify that your changes work as expected by loading the extension as an "unpacked extension" locally for each browser.
  2. Update the ./package.json and ./src/extension/manifest.json version numbers.
  3. Commit changes and tag your version as a github release.
  4. Publish a new version to npm using npm publish in the root of the project. We're publishing to npm to allow other projects to have a dependency on devtools.
  5. Run npm run zip to pack all of the builds for submission.
  6. Create a new release in the Chrome/Firefox web stores (following the instructions for each browser in the sections below), uploading the zip bundle.

Chrome

Testing locally

  1. In your Chrome URL bar, go to: chrome://extensions/
  2. Click on Load unpacked.
  3. Add the apollo-client-devtools/build directory.
  4. The add-on should now be installed.

Submit for review

  1. Login to the Chrome webstore and access the Developer Dashboard.
  2. Select the Apollo Client Devtools extension to update.
  3. Click on Package then Upload new package.
  4. Select the ./dist/chrome.zip file for upload.
  5. Click on "Submit for review".

Firefox

Testing locally

  1. In your Firefox URL bar, go to: about:debugging#/runtime/this-firefox
  2. Click on Load Temporary Add-on.
  3. Add the apollo-client-devtools/dist/apollo_client_developer_tools-X.X.X.zip file.
  4. The add-on should now be installed.

Submit for review

  1. Login to the Firefox developer hub (user/pass is in our shared password system as "Firefox Developer Account").
  2. Once logged in, click on the Apollo Client Developer Tools "Edit Product Page" link.
  3. Click on the "Upload New Version" link in the top left side menu.
  4. Agree to any new Firefox distribution agreements or policies that might show up.
  5. When the "Submit a New Version" page shows, click on the file upload button in the "Upload Version" section (keeping "Firefox" as the only option checked in the compatible application section).
  6. Choose the apollo-client-devtools/dist/apollo_client_developer_tools-X.X.X.zip for upload and submit.
  7. After the file has been validated, continue with the submission.

Code of Conduct

This project is governed by the Apollo Code of Conduct.

Maintainers

Who is Apollo?

Apollo builds open-source software and a graph platform to unify GraphQL across your apps and services. We help you ship faster with:

  • Apollo Studio – A free, end-to-end platform for managing your GraphQL lifecycle. Track your GraphQL schemas in a hosted registry to create a source of truth for everything in your graph. Studio provides an IDE (Apollo Explorer) so you can explore data, collaborate on queries, observe usage, and safely make schema changes.
  • Apollo Federation – The industry-standard open architecture for building a distributed graph. Use Apollo’s gateway to compose a unified graph from multiple subgraphs, determine a query plan, and route requests across your services.
  • Apollo Client – The most popular GraphQL client for the web. Apollo also builds and maintains Apollo iOS and Apollo Android.
  • Apollo Server – A production-ready JavaScript GraphQL server that connects to any microservice, API, or database. Compatible with all popular JavaScript frameworks and deployable in serverless environments.

Learn how to build with Apollo

Check out the Odyssey learning platform, the perfect place to start your GraphQL journey with videos and interactive code challenges. Join the Apollo Community to interact with and get technical help from the GraphQL community.


Author: apollographql
Source Code: https://github.com/apollographql/apollo-client-devtools
License: MIT License

#apollo #graphql 

Apollo Client Devtools: Apollo Client Browser Developer Tools.

ApolloDeveloperKit: Visual Debugger for Apollo IOS GraphQL Client

ApolloDeveloperKit

Apollo Client Devtools bridge for Apollo iOS.

Overview

ApolloDeveloperKit is an iOS / macOS library which works as a bridge between Apollo iOS client and Apollo Client Developer tools.

This library adds an ability to watch the sent queries or mutations simultaneously, and also has the feature to request arbitrary operations from embedded GraphiQL console.

Screenshots

apollo-developer-kit-animation

Prerequisites

Compatibility

If your are using Apollo < 0.34.0, use ApolloDeveloperKit <= 0.15.0.

Installation

CocoaPods

Add the following lines to your Podfile.

pod 'Apollo'
pod 'ApolloDeveloperKit', '~> 0.15.0', configurations: ['Debug']

Then run pod install.

Carthage

Add the following lines to your Cartfile.

github "apollographql/apollo-ios"
github "manicmaniac/ApolloDeveloperKit"

Then run carthage update --platform iOS --use-xcframeworks or carthage update --platform Mac --use-xcframeworks.

You just need to drag and drop ApolloDeveloperKit.xcframework to your project.

Swift Package Manager

Add https://github.com/manicmaniac/ApolloDeveloperKit to your dependencies.

Since Xcode 12 has only limited support for resources installed via Swift Package Manager, I recommend to use Xcode 12.4 or newer for Swift Package Manager users.

Setup

First, you need to declare a long-lived variable where ApolloDebugServer belongs to, because as soon as you release the server, it stops running.

The following code assumes you already have a procedure that instantiates ApolloClient in AppDelegate.

class AppDelegate: UIResponder, UIApplicationDelegate {
    private var server: ApolloDebugServer!
    private var client: ApolloClient!
}

In order to hook Apollo's cache and network layer, you need to use DebuggableRequestChainNetworkTransport and DebuggableNormalizedCache instead of usual RequestChainNetworkTransport and NormalizedCache.

So the second step is to declare ApolloStore using DebuggableNormalizedCache.

Normally it should be put in the beginning of application, like UIApplication.application(_:didFinishLaunchingWithOptions:).

let cache = DebuggableNormalizedCache(cache: InMemoryNormalizedCache())
let store = ApolloStore(cache: cache)

Third, configure network layer and instantiate ApolloClient with debuggable ingredients.

let interceptorProvider = LegacyInterceptorProvider(store: store)
let networkTransport = DebuggableRequestChainNetworkTransport(interceptorProvider: interceptorProvider, endpointURL: url)
self.client = ApolloClient(networkTransport: networkTransport: store: store)

Finally, create ApolloDebugServer and run.

self.server = ApolloDebugServer(networkTransport: networkTransport, cache: cache)
self.server.start(port: 8081)

See Example/{iOS,macOS}/AppDelegate.swift for full examples.

Usage

If you don't have Apollo Client Developer Tools, install it before proceeding the following steps.

Currently ApolloDeveloperKit supports only version 2.x of Apollo Client Developer Tools.

  1. Launch your app on your device or simulator.
  2. Open your browser and jump to the server's URL (in case your app runs the above example on a simulator, the URL would be http://localhost:8081).
    • You will see ApolloDebugServer is running! on your browser's tab.
    • If not, make sure the server runs and the specified URL is correct.
    • On a real device, the host would be other than localhost but you can check what it is with ApolloDebugServer.serverURL.
  3. Open developer tools.
  4. Select Apollo tab.
    • You will see tabs like GraphiQL, Queries, Mutations on the left pane.
    • If not, reload the tab and wait until it's connected again.

Excluding ApolloDeveloperKit from Release (App Store) Builds

All instructions in this section are written based on Flipboard/FLEX's way.

Since ApolloDeveloperKit is originally designed for debug use only, it should not be exposed to end-users.

Fortunately, it is easy to exclude ApolloDeveloperKit framework from Release builds. The strategies differ depending on how you integrated it in your project, and are described below.

Please make sure your code is properly excluding ApolloDeveloperKit with #if DEBUG statements before starting these instructions. Otherwise it will be linked to your app unexpectedly. See Example/AppDelegate.swift to see how to do it.

For CocoaPods users

CocoaPods automatically excludes ApolloDeveloperKit from release builds if you only specify the Debug configuration for CocoaPods in your Podfile.

For Carthage users

  1. Do NOT add ApolloDeveloperKit.framework to the embedded binaries of your target, as it would otherwise be included in all builds (therefore also in release ones).
  2. Instead, add $(PROJECT_DIR)/Carthage/Build/iOS or $(PROJECT_DIR)/Carthage/Build/Mac to your target Framework Search Paths (this setting might already be present if you already included other frameworks with Carthage). This makes it possible to import the ApolloDeveloperKit framework from your source files. It does not harm if this setting is added for all configurations, but it should at least be added for the debug one.
  3. Add a Run Script Phase to your target (inserting it alter the existing Link Binary with Libraries phase, for example), and which will embed ApolloDeveloperKit.framework in debug builds only:
if [ "$CONFIGURATION" = Debug ]; then
  /usr/local/bin/carthage copy-frameworks
fi

Finally, add $(SRCROOT)/Carthage/Build/iOS/ApolloDeveloperKit.framework or $(SRCROOT)/Carthage/Build/Mac/ApolloDeveloperKit.framework as input file of this script phase.

For users those who copy all the source files to the project manually

Now there's no easy way but you can exclude ApolloDeveloperKit by setting user defined build variable named EXCLUDED_SOURCE_FILE_NAMES. The value for the variable is a space-separated list of each filenames in ApolloDeveloperKit. Sorry for the inconvenience.

Console Redirection

ApolloDeveloperKit supports console redirection. When it is enabled, all logs written in stdout (usually written with print()) and stderr (written with NSLog()) are redirected to the web browser's console as well.

This feature is disabled by default so you may want to enable it explicitly.

debugServer = ApolloDebugServer(networkTransport: networkTransport, cache: cache)
debugServer.enableConsoleRedirection = true

Then open the console in your browser's developer tools. You will see logs in your iPhone or simulator.

In the browser console, logs written in stdout are colored in blue-green and stderr are orange so that you can distinguish them from ordinary browser logs.

console-redirection.png

Development

API Documentation

Auto-generated API documentation is here.

Run Example App

Since Example app is slightly modified version of apollographql/frontpage-ios-app, you need to start apollographql/frontpage-server before running the app.

  1. Open Xcode and select ApolloDeveloperKitExample scheme.
  2. Run and open http://localhost:8081 in your browser.

Author: manicmaniac
Source Code: https://github.com/manicmaniac/ApolloDeveloperKit
License: MIT License

#apollo #graphql 

ApolloDeveloperKit: Visual Debugger for Apollo IOS GraphQL Client
Delbert  Ferry

Delbert Ferry

1651827600

Apollo Tracing: A GraphQL Extension for Performance Tracing

Apollo Tracing


[2022-02-16] Notice: This tracing format was designed to provide tracing data from graphs to the Apollo Engine engineproxy, a project which was retired in 2018. We learned that a trace format which describes resolvers with a flat list of paths (with no way to aggregate similar nodes or repeated path prefixes) was inefficient enough to have real impacts on server performance, and so we have not been actively developing consumers or producers of this format for several years. Apollo Server (as of v3) no longer ships with support for producing this format, and engineproxy which consumed it is no longer supported. We suggest that people looking for formats for describing performance traces consider either the Apollo Studio protobuf-based trace format or a more generic format such as OpenTelemetry.


Apollo Tracing is a GraphQL extension for performance tracing.

Thanks to the community, Apollo Tracing already works with most popular GraphQL server libraries, including Node, Ruby, Scala, Java, Elixir, Go and .NET, and it enables you to easily get resolver-level performance information as part of a GraphQL response.

Apollo Tracing works by including data in the extensions field of the GraphQL response, which is reserved by the GraphQL spec for extra information that a server wants to return. That way, you have access to performance traces alongside the data returned by your query.

It’s already supported by Apollo Engine, and we’re excited to see what other kinds of integrations people can build on top of this format.

We think this format is broadly useful, and we’d love to work with you to add support for it to your tools of choice. If you’re looking for a first idea, we especially think it would be great to see support for Apollo Tracing in GraphiQL and the Apollo Client developer tools!

If you’re interested in working on support for other GraphQL servers, or integrations with more tools, please get in touch on the #apollo-tracing channel on the Apollo Slack.

Supported GraphQL Servers

Response Format

The GraphQL specification allows servers to include additional information as part of the response under an extensions key:

The response map may also contain an entry with key extensions. This entry, if set, must have a map as its value. This entry is reserved for implementors to extend the protocol however they see fit, and hence there are no additional restrictions on its contents.

Apollo Tracing exposes trace data for an individual request under a tracing key in extensions:

{
  "data": <>,
  "errors": <>,
  "extensions": {
    "tracing": {
      "version": 1,
      "startTime": <>,
      "endTime": <>,
      "duration": <>,
      "parsing": {
        "startOffset": <>,
        "duration": <>,
      },
      "validation": {
        "startOffset": <>,
        "duration": <>,
      },
      "execution": {
        "resolvers": [
          {
            "path": [<>, ...],
            "parentType": <>,
            "fieldName": <>,
            "returnType": <>,
            "startOffset": <>,
            "duration": <>,
          },
          ...
        ]
      }
    }
  }
}

Collected data

  • The startTime and endTime of the request are timestamps in RFC 3339 format with at least millisecond but up to nanosecond precision (depending on platform support).

Some more details (adapted from the description of the JSON encoding of Protobuf's Timestamp type):

A timestamp is encoded as a string in the RFC 3339 format. That is, the format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" where {year} is always expressed using four digits while {month}, {day}, {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone is required, though only UTC (as indicated by "Z") is presently supported. For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past 01:30 UTC on January 15, 2017. In JavaScript, one can convert a Date object to this format using the standard toISOString() method. In Python, a standard datetime.datetime object can be converted to this format using strftime with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use the Joda Time's ISODateTimeFormat.dateTime() to obtain a formatter capable of generating timestamps in this format.

Resolver timings should be collected in nanoseconds using a monotonic clock like process.hrtime() in Node.js or System.nanoTime() in Java.

The limited precision of numbers in JavaScript is not an issue for our purposes, because Number.MAX_SAFE_INTEGER nanoseconds is about 104 days, which should be plenty even for long running requests!

The server should keep the start time of the request both as wall time, and as monotonic time to calculate startOffsets and durations (for the request as a whole and for individual resolver calls, see below).

The duration of a request is in nanoseconds, relative to the request start, as an integer.

The startOffset of parsing, validation, or a resolver call is in nanoseconds, relative to the request start, as an integer.

The duration of parsing, validation, or a resolver call is in nanoseconds, relative to the resolver call start, as an integer.

The end of a resolver call represents the return of a value for a field, but it does not include resolving subfields. If an asynchronous value such as a promise is returned from a resolver however, the resolver call isn't considered to have ended until the asynchronous value has been resolved.

The path is the response path of the current resolver in a format similar to the error result format specified in the GraphQL specification:

This field should be a list of path segments starting at the root of the response and ending with the field associated with the error. Path segments that represent fields should be strings, and path segments that represent list indices should be 0‐indexed integers. If the error happens in an aliased field, the path to the error should use the aliased name, since it represents a path in the response, not in the query.

parentType, fieldName and returnType are strings that reflect the runtime type information usually passed to resolvers (e.g. in the info argument for graphql-js).

Example

query {
  hero {
    name
    friends {
      name
    }
  }
}
{
  "data": {
    "hero": {
      "name": "R2-D2",
      "friends": [
        {
          "name": "Luke Skywalker"
        },
        {
          "name": "Han Solo"
        },
        {
          "name": "Leia Organa"
        }
      ]
    }
  },
  "extensions": {
    "tracing": {
      "version": 1,
      "startTime": "2017-07-28T14:20:32.106Z",
      "endTime": "2017-07-28T14:20:32.109Z",
      "duration": 2694443,
      "parsing": {
        "startOffset": 34953,
        "duration": 351736,
      },
      "validation": {
        "startOffset": 412349,
        "duration": 670107,
      },
      "execution": {
        "resolvers": [
          {
            "path": [
              "hero"
            ],
            "parentType": "Query",
            "fieldName": "hero",
            "returnType": "Character",
            "startOffset": 1172456,
            "duration": 215657
          },
          {
            "path": [
              "hero",
              "name"
            ],
            "parentType": "Droid",
            "fieldName": "name",
            "returnType": "String!",
            "startOffset": 1903307,
            "duration": 73098
          },
          {
            "path": [
              "hero",
              "friends"
            ],
            "parentType": "Droid",
            "fieldName": "friends",
            "returnType": "[Character]",
            "startOffset": 1992644,
            "duration": 522178
          },
          {
            "path": [
              "hero",
              "friends",
              0,
              "name"
            ],
            "parentType": "Human",
            "fieldName": "name",
            "returnType": "String!",
            "startOffset": 2445097,
            "duration": 18902
          },
          {
            "path": [
              "hero",
              "friends",
              1,
              "name"
            ],
            "parentType": "Human",
            "fieldName": "name",
            "returnType": "String!",
            "startOffset": 2488750,
            "duration": 2141
          },
          {
            "path": [
              "hero",
              "friends",
              2,
              "name"
            ],
            "parentType": "Human",
            "fieldName": "name",
            "returnType": "String!",
            "startOffset": 2501461,
            "duration": 1657
          }
        ]
      }
    }
  }
}

Compression

We recommend that people enable compression in their GraphQL server, because the tracing format adds to the response size, but compresses well.

Although we tried other approaches to make the tracing format more compact (including deduplication of keys, common items, and structure) this complicated generating and interpreting trace data, and didn't bring the size down as much as compressing the entire HTTP response body does.

In our tests on Node.js, the processing overhead of compression is less than the overhead of sending additional bytes for an uncompressed response. But more test results from different server environments are definitely welcome, so we can help people make an informed decision about this.


Author: apollographql
Source Code: https://github.com/apollographql/apollo-tracing
License: 

#graphql 

Apollo Tracing: A GraphQL Extension for Performance Tracing

Crystal Gql: GraphQL Client Shard inspired By Apollo Client.

GraphQL Client for Crystal

A GraphQL client shard for the Crystal language.

  • Version: 0.1.3
  • Crystal Version: 0.35.1

Usage

Installing

Just add this to your shards.yml file:

dependencies:

  crystal-gql:
    github: itsezc/crystal-gql

Then run:

shards install

Initializing

require "crystal-gql"

# Define the client
api = GraphQLClient.new "https://countries.trevorblades.com"

Querying

# useQuery
data, error, loading = api.useQuery(GQL {
    "continents" => [
        "code",
        "name",
        {
            "countries" => [
                "name",
                "capital",
                {
                    "languages" => [
                        "name"
                    ]
                }
            ]
        }
    ]
})

# or traditional queries
data, error, loading = api.query("{
    continents {
        code
        name
        countries {
              name
              capital
              languages {
                    name
              }
        }
    }
}")

# Print data
print data

Querying

With authentication:

api.add_header("Authorization", "Bearer: TOKEN")
# useQuery
data, error, loading = api.useQuery(GQL {
    "continents" => [
        "code",
        "name",
        {
            "countries" => [
                "name",
                "capital",
                {
                    "languages" => [
                        "name"
                    ]
                }
            ]
        }
    ]
})

Author: itsezc
Source Code: https://github.com/itsezc/crystal-gql
License: MIT License

#graphql #apollo 

Crystal Gql: GraphQL Client Shard inspired By Apollo Client.

Connect to GraphQL APIs in Your Vue Application

Apollo Vue: How to Connect to GraphQL APIs in Vue JS

In this tutorial, you will learn how to connect to GraphQL APIs in your Vue application. You will use a really great library called Apollo for Vue which works well with Vue 3.


How To Use GraphQL APIs in Vue.js Apps

In this post, we are going to take a look at how we can make use of the GraphQL API within our Vue.JS based application. 

Add Apollo Client to Vue.JS project

In order for our app to communicate with our Strapi GraphQL API, we are going to add some additional packages to our Vue.JS Application. The package we are going to is the Apollo client and the Additional Vue-Apollo

What is Apollo ?

Apollo is a set of tools and community effort to help you use GraphQL in your apps. It’s well known for its client and its server

Apollo Client brings a tool to front-end development to make GraphQL queries/mutations easier. It acts as an HTTP client that connects to a GraphQL API and provides caching, error handling, and even state management capabilities.

We need to install a number of packages to our application, so using whichever package manager you prefer install the following dependencies. In my case I will use npm

npm install apollo-client apollo-link-http apollo-cache-inmemory apollo-link-error vue-apollo graphql graphql-tag

We are making use of environment variables in our Vue.JS application, so we are going to add an additional variable to both our env.development and env.production files which will contain the link to our Development and Production URL’s to our API.

Our Development environment will look something similar too

VUE_APP_SOURCELINK_API_URL='https://localhost:1337/graphql'

We can start to implement our Apollo configuration, in order to do so we will create a new folder in ~/src folder and call it graphql, you can name this folder whatever you want, but I am going to call it graphql as it just defines what it’s purpose is.

In the folder we’ll create a new JavaScript file and cunningly name it apollo.js , then we’ll add the following code

import Vue from 'vue';
import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import { onError } from 'apollo-link-error';
import { InMemoryCache } from 'apollo-cache-inmemory';
import VueApollo from 'vue-apollo';
const httpLink = new HttpLink({
 uri: process.env.VUE_APP_SOURCELINK_API_URL,
});
// Error Handling
const errorLink = onError(({ graphQLErrors, networkError }) => {
 if (graphQLErrors) {
   graphQLErrors.map(({ message, locations, path }) => console.log(
     <code data-enlighter-language="generic" class="EnlighterJSRAW">[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}</code>,
   ));
 }
 if (networkError) console.log(<code data-enlighter-language="generic" class="EnlighterJSRAW">[Network error]: ${networkError}</code>);
});

// Create the apollo client
export const apolloClient = new ApolloClient({
 link: errorLink.concat(httpLink),
 cache: new InMemoryCache(),
 connectToDevTools: true,
});
Vue.use(VueApollo);
export const apolloProvider = new VueApollo({
 defaultClient: apolloClient,
});

There is quite a bit to explain in the code, but essentially HttpLink is an object that requires a uri property, which refers to the GraphQL endpoint from the API being used. Ex: localhost:1337/graphql

A new ApolloClient instance needs to be created, where the link, cache instance, and further options can be set.

We wrap our ApolloClient inside a VueApollo instance so we can use its hooks inside our Vue components.
 

We have started to add the capability to introduce some error handling and logging using the errorLink , for now we are simply going to log this to console window, but in future will implement a more robust set of utilities.

We will also now need edit our main.js to import our ApolloProvider and add it to our Vue instance.

import 'bootstrap-css-only/css/bootstrap.min.css';
import 'mdbvue/build/css/mdb.css';
import Vue from 'vue';
import { firestorePlugin } from 'vuefire';
import App from './App.vue';
import router from './router';
import store from './store';
import './registerServiceWorker';
import { apolloProvider } from './graphql/apollo';
Vue.config.productionTip = false;
Vue.use(firestorePlugin);
new Vue({
 router,
 store,
 apolloProvider,
 render: h => h(App),
}).$mount('#app');

Create your GraphQL queries

We are now going to create a folder to contain all our GraphQL queries. In our particular application we will not be using mutations and our app will only be using our GraphQL API to access read-only reference data at this stage. Therefore we will only be adding one folder name queries.

In the queries folder we’ll create a new JavaScript file name skillQueries.js which will use to add all our Skill Specific queries. Add the following code

import gql from 'graphql-tag';
// eslint-disable-next-line import/prefer-default-export
export const GET_LANGUAGES_QUERY = gql<code data-enlighter-language="generic" class="EnlighterJSRAW">\n query getLanguages {\n  languages( where: { Active: true } ) {\n    nameWe\n  }  \n}</code>;

You may notice the query from Creating Reference Data API with Strapi and using GraphQL, we have deliberately kept it simple at this stage, so we don’t get bogged down in the complexities of GraphQL and we are just interested in getting this example to work.

Edit Skills View

All our configuration work is now done and we are now ready to consume our API in our application. In our Application we have created Skill.vue file which will be used to enable users to select their appropriate skills.

This is where we are going contact the API when the view loads and populate an Autocomplete text box with the values. We make use of MDB Vue Pro Material Component Framework to help to quickly create good looking UI.

In our example we are going to keep the UI as simple as possible so as not to distract from the implementation. We will use a Select List to display the items from the API and enable the user to select items to add to another List Item.

template>
 <mdb-container class="mt-5 p-5">
   <h1>Skills</h1>
   <mdb-row class="mt-3 p-3">
     <mdb-col>
       <mdb-card>
         <mdb-card-body>
           <mdb-card-title class="section-title">Programming Languages</mdb-card-title>
           <mdb-row>
             <mdb-col>
               <mdb-select search v-model="languages"
                           id="language"
                           label="Language"
                           @getvalue="selectedLanguage"/>
             </mdb-col>
             <mdb-col>
              <mdb-btn @click="addLanguage">
                <mdb-icon icon="plus"></mdb-icon>
              </mdb-btn>
             </mdb-col>
           </mdb-row>
           <mdb-row>
             <mdb-col>
               <mdb-list-group>
                 <mdb-list-group-item v-for="language in selLanguage"
                                      v-bind:key="language">{{ language }}
                 </mdb-list-group-item>
               </mdb-list-group>
             </mdb-col>
           </mdb-row>
         </mdb-card-body>
       </mdb-card>
     </mdb-col>
     <mdb-col></mdb-col>
   </mdb-row>
 </mdb-container>
</template>

Our application will look similar to this, with just enough to illustrate the functionality.

Populate Languages Select Box

We are going to make a call to our Reference Data API to get the values to populate our List box with making use of our Apollo implementation we defined earlier.

We are going to mark our mounted method as async so we don’t slow down view loading.

 data() {
   return {
     languages: [],
     selectedLanguages: [],
   };
 },
 async mounted() {
   this.$apollo.query({ query: GET_LANGUAGES_QUERY })
     .then((response) => {
       response.data.languages.forEach((language) => {
         this.languages.push({ text: language.name, value: language.name });
       });
     });
   this.languages.sort();
 },

If you start the application now, and ensure that your API is available. Your page will now load and the values will now be loaded in the select box.

Enable selection

We will now complete our example, with an implementation to select items from the list to populate our list of selected programming skills.

This is just rudimentary code, to implement an initial set of functionality. In forthcoming tutorials we are going to completely refactor this code, to enable other Vue.JS specific functionality and neaten up the UI a lot more.

methods: {
   addLanguage() {
     const selected = this.selectedLanguage();
     if (selected !== undefined && !this.selectedLanguages.includes(selected)) {
       this.selectedLanguages.push(selected);
       this.selectedLanguages.sort();
     }
   },
   selectedLanguage() {
     const language = this.languages.find(option => option.selected === true);
     if (language) {
       return language.value;
     }
   },
 },

For the purpose of our Demonstration and topic of this specific tutorial we are now complete.

Summary

In this tutorial, we have focused on how to configure our Vue.JS application to start to access a Strapi Reference Data API using GraphQL and the Apollo client.

This is a very basic implementation and we will now continue to build on this implementation over the course of a number of tutorials detailing how we will be building an Web and Mobile application for a software developer community website.

#apollo #vue #graphql #api #vue3 

Connect to GraphQL APIs in Your Vue Application
Franz  Becker

Franz Becker

1651662000

A Mocked Managed Federation Supgraph using Apollo Server 3.x

An example of mocking a mangaged federation apollo-gateway powered by apollo server 3.x.

Since it is a managed federation gateway, the mocked schema is the supergraph from Apollos Schema Registry

Assumptions

  • You already have an Apollo Studio organization / account
  • At least one subgraph has been published to the schema registry for the below mentioned has been published for the APOLLO_KEY and APOLLO_GRAPH_REF pair

Getting started

  1. cp .env.template .env
  2. Edit .env and set a valid APOLLO_KEY and APOLLO_GRAPH_REF pair
  3. Run npm install && npm run dev

Author: setchy
Source Code: https://github.com/setchy/apollo-server-3-mocked-federation
License: 

#typescript #apollo 

A Mocked Managed Federation Supgraph using Apollo Server 3.x
Franz  Becker

Franz Becker

1651626000

Apollo React Example for Github GraphQL API with Create-react-app

react-apollo-graphql-github-example

Apollo React example for Github GraphQL API with create-react-app

Prerequisites

Install

git clone https://github.com/katopz/react-apollo-graphql-github-example.git
cd react-apollo-graphql-github-example
npm i

Config

  • Copy config.default.js into a file called config.js, and replace xxx with your username and password
  • Replace GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET with your credential.

Develop

npm start

For VSCode you can press F5 to run :)

More examples

Referer


Author: katopz
Source Code: https://github.com/katopz/react-apollo-graphql-github-example
License: MIT License

#apollo #graphql #react-native 

Apollo React Example for Github GraphQL API with Create-react-app
Sean Wade

Sean Wade

1650510251

Demystifying GraphQL Typings Generation

Demystifying GraphQL Typings Generation

Many developers use tools such as Apollo Client to generate TypeScript types from their GraphQL schemas. Let's go over how those tools read from standard GraphQL endpoints to introspect your APIs and generate TypeScript types for you.

#graphql #apollo #typescript 

Demystifying GraphQL Typings Generation
Layne  Fadel

Layne Fadel

1648627200

Apollo Server Is A Community-maintained Open-source GraphQL Server

A TypeScript GraphQL Server for Express, Koa, Hapi, Lambda, and more.

Apollo Server is a community-maintained open-source GraphQL server. It works with many Node.js HTTP server frameworks, or can run on its own with a built-in Express server. Apollo Server works with any GraphQL schema built with GraphQL.js--or define a schema's type definitions using schema definition language (SDL).

Read the documentation for information on getting started and many other use cases and follow the CHANGELOG for updates.

Principles

Apollo Server is built with the following principles in mind:

  • By the community, for the community: Its development is driven by the needs of developers.
  • Simplicity: By keeping things simple, it is more secure and easier to implement and contribute.
  • Performance: It is well-tested and production-ready.

Anyone is welcome to contribute to Apollo Server, just read CONTRIBUTING.md, take a look at the roadmap and make your first PR!

Getting started

To get started with Apollo Server:

  • Install with npm install apollo-server-<integration> graphql
  • Write a GraphQL schema
  • Use one of the following snippets

There are two ways to install Apollo Server:

  • Standalone: For applications that do not require an existing web framework, use the apollo-server package.
  • Integrations: For applications with a web framework (e.g. express, koa, hapi, etc.), use the appropriate Apollo Server integration package.

For more info, please refer to the Apollo Server docs.

Installation: Standalone

In a new project, install the apollo-server and graphql dependencies using:

npm install apollo-server graphql

Then, create an index.js which defines the schema and its functionality (i.e. resolvers):

const { ApolloServer, gql } = require('apollo-server');

// The GraphQL schema
const typeDefs = gql`
  type Query {
    "A simple type for getting started!"
    hello: String
  }
`;

// A map of functions which return data for the schema.
const resolvers = {
  Query: {
    hello: () => 'world',
  },
};

const server = new ApolloServer({
  typeDefs,
  resolvers,
});

server.listen().then(({ url }) => {
  console.log(`🚀 Server ready at ${url}`);
});

Due to its human-readability, we recommend using schema-definition language (SDL) to define a GraphQL schema--a GraphQLSchema object from graphql-js can also be specified instead of typeDefs and resolvers using the schema property:

const server = new ApolloServer({
  schema: ...
});

Finally, start the server using node index.js and go to the URL returned on the console.

For more details, check out the Apollo Server Getting Started guide and the fullstack tutorial.

For questions, the Apollo community forum is a great place to get help.

Installation: Integrations

While the standalone installation above can be used without making a decision about which web framework to use, the Apollo Server integration packages are paired with specific web frameworks (e.g. Express, Koa, hapi).

The following web frameworks have Apollo Server integrations, and each of these linked integrations has its own installation instructions and examples on its package README.md:

Context

A request context is available for each request. When context is defined as a function, it will be called on each request and will receive an object containing a req property, which represents the request itself.

By returning an object from the context function, it will be available as the third positional parameter of the resolvers:

new ApolloServer({
  typeDefs,
  resolvers: {
    Query: {
      books: (parent, args, context, info) => {
        console.log(context.myProperty); // Will be `true`!
        return books;
      },
    }
  },
  context: async ({ req }) => {
    return {
      myProperty: true
    };
  },
})

Documentation

The Apollo Server documentation contains additional details on how to get started with GraphQL and Apollo Server.

The raw Markdown source of the documentation is available within the docs/ directory of this monorepo--to contribute, please use the Edit on GitHub buttons at the bottom of each page.

Development

If you wish to develop or contribute to Apollo Server, we suggest the following:

Fork this repository

Install Direnv (a tool that automatically sets up environment variables in project directories) or nvm. We use nvm to ensure we're running the expected version of Node (and we use Direnv to install and run nvm automatically).

Install the Apollo Server project on your computer

git clone https://github.com/[your-user]/apollo-server
cd apollo-server
direnv allow  # sets up nvm for you; if you installed nvm yourself, try `nvm install` instead
  • Build and test
npm install
npm test
  • To run individual test files, run npm run pretest && npx jest packages/apollo-server-foo/src/__tests__/bar.test.ts. Note that you do need to re-compile TypeScript before each time you run a test, or changes across packages may not be picked up. Instead of running npm run pretest from scratch before each test run, you can also run tsc --build tsconfig.json --watch in another shell, or use the VSCode Run Build Task to run that for you.

Community

Are you stuck? Want to contribute? Come visit us in the Apollo community forum!

Maintainers

Who is Apollo?

Apollo builds open-source software and a graph platform to unify GraphQL across your apps and services. We help you ship faster with:

  • Apollo Studio – A free, end-to-end platform for managing your GraphQL lifecycle. Track your GraphQL schemas in a hosted registry to create a source of truth for everything in your graph. Studio provides an IDE (Apollo Explorer) so you can explore data, collaborate on queries, observe usage, and safely make schema changes.
  • Apollo Federation – The industry-standard open architecture for building a distributed graph. Use Apollo’s gateway to compose a unified graph from multiple subgraphs, determine a query plan, and route requests across your services.
  • Apollo Client – The most popular GraphQL client for the web. Apollo also builds and maintains Apollo iOS and Apollo Android.
  • Apollo Server – A production-ready JavaScript GraphQL server that connects to any microservice, API, or database. Compatible with all popular JavaScript frameworks and deployable in serverless environments.

Learn how to build with Apollo

Check out the Odyssey learning platform, the perfect place to start your GraphQL journey with videos and interactive code challenges. Join the Apollo Community to interact with and get technical help from the GraphQL community.


Author: apollographql
Source Code: https://github.com/apollographql/apollo-server
License: MIT License

#graphql #apollo 

Apollo Server Is A Community-maintained Open-source GraphQL Server
Layne  Fadel

Layne Fadel

1648562400

Ember Apollo Client: An Ember-cli Addon for Apollo Client and GraphQL.

ember-apollo-client

Use @apollo/client and GraphQL from your Ember app.

This addon is battle tested: it has been used to build several large apps. As such, we've solved real-world problems such as reliable testing and preventing resource leaks by unsubscribing from watch queries.

Installation

ember install ember-apollo-client

This should also automatically install ember-fetch and graphql.

Install the Apollo Client Developer tools for Chrome for a great GraphQL developer experience!

Compatibility

  • Apollo Client v3.0 or above
  • Ember.js v3.24 or above
  • Ember CLI v2.13 or above
  • Node.js v12 or above
  • FastBoot 1.0+

For compatibility with Ember versions below 3.4, use version 1.x. For compatibility with Apollo Client v1 or v2, use version 1.x or 2.x of this addon.

Configuration

Runtime configuration

In your app's config/environment.js, configure the URL for the GraphQL API.

let ENV = {
  ...
  apollo: {
    apiURL: 'https://test.example/graphql',
    // Optionally, set the credentials property of the Fetch Request interface
    // to control when a cookie is sent:
    // requestCredentials: 'same-origin', // other choices: 'include', 'omit'
  },
  ...
}

Additional configuration of the ApolloClient can be done by extending the Apollo service and overriding the clientOptions property. See the Apollo Service API for more info.

Build time configuration

In your app's ember-cli-build.js, you can set build time options for broccoli-graphql-filter to keep or remove file extensions in .graphql files.

module.exports = function(defaults) {
  let app = new EmberApp(defaults, {
    emberApolloClient: {
      keepGraphqlFileExtension: false
    }
  });

  return app.toTree();
};

keepGraphqlFileExtension = true, defaults to true – If false, creates files called my-query.js instead of my-query.graphql.js, so that you can import them as ./my-query instead of ./my-query.graphql.

Example:

import myQuery from 'my-app/queries/my-query.graphql';

Dependencies

This addon uses ember-auto-import to import dependencies.

This addon does not exposes any dependencies directly to your application, so if you desire any additional graphql or apollo dependencies, install them with npm/yarn and import as desired.

Here are some useful packages:

Make sure to use ember-auto-import in your application to import these additional packages.

Peer Dependencies

This addon has a peer dependency of:

Usage

Fetching data

GraphQL queries should be placed in external files, which are automatically made available for import:

app/gql/queries/human.graphql

query human($id: String!) {
  human(id: $id) {
    name
  }
}

You can also use the graphql-tag package to write your queries within your JS file:

import gql from "graphql-tag";

const query = gql`
  query human($id: String!) {
    human(id: $id) {
      name
    }
  }
`;

Note: Inline queries like the one above are compiled at runtime. This is both slower than external files (which are precompiled) and involves shipping extra dependencies in your vendor.js. For the time being, we recommend using external files for your queries.

If you are looking for an opportunity to contribute, enabling precompilation of inline queries would be a fantastic feature to work on.

Within your routes, you can query for data using the queryManager computed macro and watchQuery:

app/routes/some-route.js

import Route from "@ember/routing/route";
import { queryManager } from "ember-apollo-client";
import query from "my-app/gql/queries/human.graphql";

export default Route.extend({
  apollo: queryManager(),

  model(params) {
    let variables = { id: params.id };
    return this.apollo.watchQuery({ query, variables }, "human");
  }
});

This performs a watchQuery on the ApolloClient. The resulting object is a POJO.

If a subsequent query (such as a mutation) happens to fetch the same data while this query's subscription is still active, the object will immediately receive the latest attributes (just like ember-data).

Please note that when using watchQuery, you must unsubscribe when you're done with the query data. You should only have to worry about this if you're using the Apollo service directly. If you use the queryManager computed macro in your routes, or in your data-loading components or class that extend Ember.Object, all active watch queries are tracked and unsubscribed when the route is exited or the component and Ember.Object is destroyed.

You can instead use query if you just want a single query with a POJO response and no watch updates.

If you need to access the Apollo Client ObservableQuery, such as for pagination, you can retrieve it from a watchQuery result using getObservable:

import Route from "@ember/routing/route";
import { getObservable, queryManager} from "ember-apollo-client";

export default Route.extend({
  apollo: queryManager(),

  model() {
    let result = this.apollo.watchQuery(...);
    let observable = getObservable(result);
    observable.fetchMore(...) // utilize the ObservableQuery
    ...
  }
});

See the detailed query manager docs for more details on usage, or the Apollo service API if you need to use the service directly.

GraphQL Subscriptions

GQL Subscriptions allow a client to subscribe to specific queries they are interested in tracking. The syntax for doing this is similar to query / watchQuery, but there are a few main differences:

  • you must define a subscription (versus a query or mutation)
  • because subscriptions are async by nature, you have to listen for these events and act accordingly.
  • subscriptions require websockets, so must configure your link accordingly

Creating your subscription

app/gql/subscriptions/new-human.graphql

subscription {
  newHuman() {
    name
  }
}

Subscribing from inside a route

app/routes/some-route.js

import Route from '@ember/routing/route';
import { queryManager } from 'ember-apollo-client';
import query from 'app/gql/subscriptions/new-human';
import { addListener, removeListener } from '@ember/object/events';

const handleEvent = event => alert(`${event.name} was just born!`);

export default Route.extend({
  apollo: queryManager(),

  model() {
    return this.get('apollo').subscribe({ query }, 'human');
  },

  setupController(controller, model) {
    addListener(model, 'event', handleEvent);
  },

  resetController(controller, isExiting, transition) {
    if (isExiting) {
      removeListener(controller.model, 'event', handleEvent);
    }
  }
});

The big advantage of using the queryManager is that when you navigate away from this route, all subscriptions created will be terminated. That said, if you want to manually unsubscribe (or are not using the queryManager) subscription.unsubscribe() will do the trick.

Enabling Websockets

While this library should work w/ any back-end implementation, here's an example with Authenticated Phoenix + Absinthe:

my-app/services/apollo.js

import ApolloService from 'ember-apollo-client/services/apollo';
import { inject as service } from '@ember/service';
import { Socket } from 'phoenix';
import { createAbsintheSocketLink } from '@absinthe/socket-apollo-link';
import AbsintheSocket from '@absinthe/socket';

class OverriddenApollo extends ApolloService {
  @service
  session;

  link() {
    const socket = new Socket("ws://socket-url", {
      params: { token: this.get('session.token') },
    });
    const absintheSocket = AbsintheSocket.create(socket);

    return createAbsintheSocketLink(absintheSocket);
  }
}

Note: This will switch all gql communication to use websockets versus http. If you want to conditionally use websockets for only subscriptions (a common pattern) this is where Apollo Link Composition comes in. Specifically, the split function is what we're after (note we are using apollo-utilities, a helpful npm package):

my-app/services/apollo.js

import ApolloService from 'ember-apollo-client/services/apollo';
import { inject as service } from '@ember/service';
import { Socket } from 'phoenix';
import { split } from '@apollo/client';
import { getMainDefinition } from '@apollo/client/utilities';
import { createAbsintheSocketLink } from '@absinthe/socket-apollo-link';
import AbsintheSocket from '@absinthe/socket';

class OverriddenApollo extends ApolloService {
  @service
  session;

  link() {
    let httpLink = super.link();

    const socket = new Socket("ws://socket-url", {
      params: { token: this.get('session.token') },
    });
    const socketLink = createAbsintheSocketLink(AbsintheSocket.create(socket));

    return split(
      ({ query }) => {
        const { kind, operation } = getMainDefinition(query);

        return kind === 'OperationDefinition' && operation === 'subscription';
      },
      socketLink,
      httpLink
    );
  }
}

Note: You will need to add the following dependencies to your project:

yarn add -D @apollo/client
yarn add -D @absinthe/socket
yarn add -D @absinthe/socket-apollo-link

Mutations and Fragments

You can perform a mutation using the mutate method. You can also use GraphQL fragments in your queries. This is especially useful if you want to ensure that you refetch the same attributes in a subsequent query or mutation involving the same model(s).

The following example shows both mutations and fragments in action:

app/gql/fragments/review-fragment.graphql

fragment ReviewFragment on Human {
  stars
  commentary
}

app/gql/mutations/create-review.graphql

#import ReviewFragment from 'my-app/gql/fragments/review-fragment.graphql'

mutation createReview($ep: Episode!, $review: ReviewInput!) {
  createReview(episode: $ep, review: $review) {
    review {
      ...ReviewFragment
    }
  }
}

app/routes/my-route.js

import Route from "@ember/routing/route";
import { inject as service } from "@ember/service";
import mutation from "my-app/gql/mutations/create-review.graphql";

export default Route.extend({
  apollo: service(),

  actions: {
    createReview(ep, review) {
      let variables = { ep, review };
      return this.get("apollo").mutate({ mutation, variables }, "review");
    }
  }
});

Query manager API

watchQuery(options, resultKey): This calls the ApolloClient.watchQuery method. It returns a promise that resolves with a POJO. That object will be updated whenever the watchQuery subscription resolves with new data. As before, the resultKey can be used to resolve beneath the root.

The query manager will automatically unsubscribe from this object.

subscribe(options, resultKey): This calls the ApolloClient.subscribe method. It returns a promise that resolves with an EmberApolloSubscription. You can use this object in a few ways to keep track of your subscription:

  • emberApolloSubscription.lastEvent; // return the most recently received event data
//import { addListener, removeListener } from '@ember/object/events';
const result = await this.apollo.subscribe(
 {
   subscription: mySubscription,
 }
);
const handleEvent = event => {
 console.log('event received', event)
};
// Add listener to new data
addListener(result, 'event', handleEvent);
// Remove the listener from new data
removeListener(result, 'event', handleEvent);

query(options, resultKey): This calls the ApolloClient.query method. It returns a promise that resolves with the raw POJO data that the query returns. If you provide a resultKey, the resolved data is grabbed from that key in the result.

mutate(options, resultKey): This calls the ApolloClient.mutate method. It returns a promise that resolves with the raw POJO data that the mutation returns. As with the query methods, the resultKey can be used to resolve beneath the root.

Apollo service API

You should not need to use the Apollo service directly for most regular usage, instead utilizing the queryManager computed macro. However, you will probably need to customize options on the apollo service, and might need to query it directly for some use cases (such as loading data from a service rather than a route or component).

The apollo service has the following public API:

clientOptions: This function should return the options hash that will be passed to the ApolloClient constructor. You can override this function to configure the client this service uses:

class OverriddenApolloService extends ApolloService {
  clientOptions() {
    return {
      link: this.link(),
      cache: this.cache(),
    };
  }
}

link: This function provides a list of middlewares and afterwares to the Apollo Link the interface for fetching and modifying control flow of GraphQL requests. To create your middlewares/afterwares:

   link() {
    let httpLink = super.link()

    // Middleware
    let authMiddleware = setContext(async(request, context) => {
      if (!token) {
        token = await localStorage.getItem('token') || null;
      }

      Object.assign(context.headers, {
        headers: {
          authorization: token
        }
      });

      return context;
    });

    // Afterware
    const resetToken = onError(({ networkError }) => {
      if (networkError && networkError.statusCode === 401) {
        // remove cached token on 401 from the server
        token = undefined;
      }
    });

    const authFlowLink = authMiddleware.concat(resetToken);

    return authFlowLink.concat(httpLink);
  }

Example with ember-simple-auth:

import ApolloService from 'ember-apollo-client/services/apollo';
import { inject as service } from '@ember/service';
import { setContext } from '@apollo/client/link/context';
import { Promise } from 'rsvp';

class OverriddenApollo extends ApolloService {
  @service
  session;

  link() {
    let httpLink = super.link();

    let authLink = setContext((request, context) => {
      return this._runAuthorize(request, context);
    });
    return authLink.concat(httpLink);
  }

  _runAuthorize() {
    if (!this.get('session.isAuthenticated')) {
      return {};
    }
    return new Promise(success => {
      let headers = {};
      let token = this.get('session.data.authenticated.token');
      headers['Authorization'] = `Bearer ${token}`;

      success({ headers });
    });
  }
}

Note: You will need to add the following dependencies to your project:

yarn add -D @apollo/client

watchQuery(options, resultKey): This calls the ApolloClient.watchQuery method. It returns a promise that resolves with a POJO. That object will be updated whenever the watchQuery subscription resolves with new data. As before, the resultKey can be used to resolve beneath the root.

When using this method, it is important to unsubscribe from the query when you're done with it.

query(options, resultKey): This calls the ApolloClient.query method. It returns a promise that resolves with the raw POJO data that the query returns. If you provide a resultKey, the resolved data is grabbed from that key in the result.

mutate(options, resultKey): This calls the ApolloClient.mutate method. It returns a promise that resolves with the raw POJO data that the mutation returns. As with the query methods, the resultKey can be used to resolve beneath the root.

Unsubscribing from watch queries

Apollo Client's watchQuery will continue to update the query with new data whenever the store is updated with new data about the resolved objects. This happens until you explicitly unsubscribe from it.

In ember-apollo-client, most unsubscriptions are handled automatically by the queryManager computed macro, so long as you use it.

If you're fetching data elsewhere, such as in an Ember Service, or if you use the Apollo service directly, you are responsible for unsubscribing from watchQuery results when you're done with them, you can use unsubscribe:

import Service from "@ember/service";
import { unsubscribe } from "ember-apollo-client";
import { inject as service } from '@ember/service';

export default Service.extend( {
  apollo: service(),
  result: null,

  init() {
    this._super(...arguments);
    this.result = this.apollo.watchQuery(...);
  },

  willDestroy() {
    unsubscribe(this.result)
  }
});

queryManager as decorator

The queryManager computed macro can be used as a decorator when using Ember v3.10.0 or above.

import Route from '@ember/routing/route';
import { queryManager } from 'ember-apollo-client'
import query from 'my-app/gql/queries/human.graphql';

export default class MyAwesomeRoute extends Route {
  @queryManager apollo;

  model({ id }) {
    let variables = { id };
    return this.apollo.watchQuery({ query, variables });
  }
}

queryManager options

The queryManager computed macro can accept an options hash with the name of the service to use as apollo. If your application has a custom apollo service or multiple apollo services that extends from ember-apollo-client/services/apollo, you can use this option to specify which apollo service to use.

// imports ...

export default class MyAwesomeRoute extends Route {
  @queryManager({ service: 'my-custom-apollo-service' }) apollo;

  // ...
}

Use with Fastboot

Ember Apollo Client works with FastBoot out of the box as long that SSR is enabled. In order to enable SSR, define it on apollo service:

Example:

class OverriddenApolloService extends ApolloService {
  clientOptions() {
    const opts = super.clientOptions();
    return {...opts, ssrMode: true };
  }
}

Since you only want to fetch each query result once, pass the ssrMode: true option to the Apollo Client constructor to avoid repeated force-fetching.

Skipping queries for SSR

If you want to intentionally skip a query during SSR, you can pass ssr: false in the query options. Typically, this will mean the component will get rendered in its loading state on the server. For example:

actions: {
  refetchModel() {
    this.get('apollo').query({
      query,
      variables,
      // Don't run this query on the server
      ssr: false
    });
  }
}

Using With TypeScript

When using TypeScript (with ember-cli-typescript in your Ember app) you will quickly run into an error like:

Cannot find module './users.graphql'.

This error happens when you import a *.graphql file, e.g. import query from './users.graphql';. The quick solution is to use // @ts-ignore, but that is only a patch for the one place you've used the import.

To define basic types for those imports, you need to add the following to types/global.d.ts:

// Apollo GraphQL imports
declare module '*.graphql' {
  const doc: import('graphql').DocumentNode;
  export default doc;
}

Note: The graphql module above is included when you ember install ember-apollo-client.

Testing

This addon is test-ready! All promises from the apollo service are tracked with Ember.Test.registerWaiter, so your tests should be completely deterministic.

The dummy app contains example routes for mutations and queries:

The tests also contain a sample Star Wars GraphQL schema with an pretender setup for mock data.

Development

Installation

  • git clone https://github.com/ember-graphql/ember-apollo-client this repository
  • cd ember-apollo-client
  • yarn install

Linting

  • yarn run lint:hbs
  • yarn run lint:js
  • yarn run lint:js --fix

Running tests

  • ember test – Runs the test suite on the current Ember version
  • ember test --server – Runs the test suite in "watch mode"
  • ember try:each – Runs the test suite against multiple Ember versions

Running the dummy application

For more information on using ember-cli, visit https://ember-cli.com/.

Contributors

A special thanks to the following contributors:

Contributing

See the Contributing guide for details.


Author: ember-graphql
Source Code: https://github.com/ember-graphql/ember-apollo-client
License: MIT License

#graphql #apollo 

Ember Apollo Client: An Ember-cli Addon for Apollo Client and GraphQL.
Layne  Fadel

Layne Fadel

1648555200

Svelte Apollo: Svelte Integration For Apollo GraphQL

svelte-apollo

Svelte integration for Apollo GraphQL.

Example

The following simple example shows how to run a simple query with svelte-apollo.

<!-- App.svelte -->
<Books />

<script>
  import { ApolloClient } from "@apollo/client";
  import { setClient } from "svelte-apollo";
  import Books from "./Books.svelte";

  // 1. Create an Apollo client and pass it to all child components
  //    (uses svelte's built-in context)
  const client = new ApolloClient({
    /* ... */
  });
  setClient(client);
</script>
<!-- Books.svelte -->
<script>
  import { query } from "svelte-apollo";
  import { GET_BOOKS } from "./queries";

  // 2. Execute the GET_BOOKS GraphQL query using the Apollo client
  //    -> Returns a svelte store of promises that resolve as values come in
  const books = query(GET_BOOKS);
</script>

<!-- 3. Use $books (note the "$"), to subscribe to query values -->
{#if $books.loading}
  Loading...
{:else if $books.error}
  Error: {$books.error.message}
{:else}
  {#each $books.data.books as book}
    {book.title} by {book.author.name}
  {/each}
{/if}

API

# query(document[, options])

Query an Apollo client, returning a readable store of result values. Uses Apollo's watchQuery, for fetching from the network and watching the local cache for changes. If the client is hydrating after SSR, it attempts a readQuery to synchronously check the cache for values.

<script>
  import { query } from "svelte-apollo";
  import { GET_BOOKS } from "./queries";

  const books = query(GET_BOOKS, {
    // variables, fetchPolicy, errorPolicy, and others
  });

  function reload() {
    books.refetch();
  }
</script>

<ul>
  {#if $books.loading}
    <li>Loading...</li>
  {:else if $books.error}
    <li>ERROR: {$books.error.message}</li>
  {:else}
    {#each $books.data.books as book (book.id)}
      <li>{book.title} by {book.author.name}</li>
    {/each}
  {/if}
</ul>

<button on:click="{reload}">Reload</button>

Reactive variables are supported with refetch:

<script>
  import { query } from "svelte-apollo";
  import { SEARCH_BY_AUTHOR } from "./queries";

  export let author;
  let search = "";

  const books = query(SEARCH_BY_AUTHOR, {
    variables: { author, search },
  });

  // `books` is refetched when author or search change
  $: books.refetch({ author, search });
</script>

Author: {author}
<label>Search <input type="text" bind:value="{search}" /></label>

<ul>
  {#if $books.loading}
    <li>Loading...</li>
  {:else if $books.error}
    <li>ERROR: {$books.error.message}</li>
  {:else if $books.data}
    {#each $books.data.books as book (book.id)}
      <li>{book.title}</li>
    {/each}
  {:else}
    <li>No books found</li>
  {/if}
</ul>

# mutation(document[, options])

Prepare a GraphQL mutation with the Apollo client, using Apollo's mutate.

<script>
  import { mutation } from "svelte-apollo";
  import { ADD_BOOK } from "./queries";

  const addBook = mutation(ADD_BOOK);
  let title = "";
  let author = "";

  async function handleSubmit() {
    try {
      await addBook({ variables: { title, author } });
    } catch (error) {
      // TODO
    }
  }
</script>

<form on:submit|preventDefault="{handleSubmit}">
  <label for="book-author">Author</label>
  <input type="text" id="book-author" bind:value="{author}" />

  <label for="book-title">Title</label>
  <input type="text" id="book-title" bind:value="{title}" />

  <button type="submit">Add Book</button>
</form>

# subscribe(document[, options])

Subscribe using an Apollo client, returning a store that is compatible with {#await $...}. Uses Apollo's subscribe.

<script>
  import { subscribe } from "svelte-apollo";
  import { NEW_BOOKS } from "./queries";

  const newBooks = subscribe(NEW_BOOKS);
</script>

{#if $newBooks.loading}
  Waiting for new books...
{:else if $newBooks.data}
  New Book: {$newBooks.data.book}
{/if}

# restore(document, options)

Restore a previously executed query (e.g. via preload) into the Apollo cache.

<script context="module">
  import client from "./client";
  import { GET_BOOKS } from "./queries";

  export async function preload() {
    return {
      preloaded: await client.query({ query: GET_BOOKS }),
    };
  }
</script>

<script>
  import { restore } from "svelte-apollo";

  export let preloaded;

  // Load preloaded values into client's cache
  restore(GET_BOOKS, preloaded);
</script>

# setClient(client)

Set an Apollo client for the current component's and all child components' contexts.

<!-- Parent.svelte -->
<script>
  import { setClient } from "svelte-apollo";
  import client from "./client";

  setClient(client);
</script>

# getClient()

Get an Apollo client from the current component's context.

<!-- Child.svelte -->
<script>
  import { getClient } from "svelte-apollo";

  const client = getClient();
</script>

Author: timhall
Source Code: https://github.com/timhall/svelte-apollo
License: MIT License

#graphql #apollo #svelte 

Svelte Apollo: Svelte Integration For Apollo GraphQL
Layne  Fadel

Layne Fadel

1648548000

Apollo Angular: Allows You to Fetch Data From Your GraphQL Server

Apollo Angular 

Apollo Angular allows you to fetch data from your GraphQL server and use it in building complex and reactive UIs using the Angular framework. Apollo Angular may be used in any context that Angular may be used. In the browser, in NativeScript, or in Node.js when you want to do server-side rendering.

Apollo Angular requires no complex build setup to get up and running. As long as you have a GraphQL server you can get started building out your application with Angular immediately. Apollo Angular works out of the box with both Angular CLI (ng add apollo-angular) and NativeScript with a single install.

Apollo Angular is:

  1. Incrementally adoptable, so that you can drop it into an existing JavaScript app and start using GraphQL for just part of your UI.
  2. Universally compatible, so that Apollo works with any build setup, any GraphQL server, and any GraphQL schema.
  3. Simple to get started with, so you can start loading data right away and learn about advanced features later.
  4. Inspectable and understandable, so that you can have great developer tools to understand exactly what is happening in your app.
  5. Built for interactive apps, so your users can make changes and see them reflected in the UI immediately.
  6. Small and flexible, so you don't get stuff you don't need. The core is under 12kb compressed.
  7. Community driven, because Apollo is driven by the community and serves a variety of use cases. Everything is planned and developed in the open.

Get started today on the app you’ve been dreaming of, and let Apollo Angular take you to the moon!

Installation

It is simple to install Apollo Angular and related libraries

# installing Apollo Angular in Angular CLI
ng add apollo-angular

# installing each piece independently
yarn add @apollo/client apollo-angular graphql

That’s it! You may now use Apollo Angular in any of your Angular environments.

For an amazing developer experience you may also install the Apollo Client Developer tools for Chrome which will give you inspectability into your Apollo Angular data.

  • If you are using Apollo-Client v3, please make sure to use apollo-angular@v3

If you are using Apollo-Client v2, please make sure to use apollo-angular@v1 (and for Angular 10 support, make sure to use v1.10.0)

Usage

Now you may create components that are connected to your GraphQL API.

Finally, to demonstrate the power of Apollo Angular in building interactive UIs let us connect one of your components to your GraphQL server using the Apollo service:

import {Component, OnInit} from '@angular/core';
import {Apollo, gql} from 'apollo-angular';

const GET_DOGS = gql`
  {
    dogs {
      id
      breed
    }
  }
`;

@Component({
  selector: 'dogs',
  template: `
    <ul>
      <li *ngFor="let dog of dogs | async">
        {{dog.breed}}
      </li>
    </ul>
  `,
})
export class DogsComponent implements OnInit {
  dogs: Observable<any>;

  constructor(private apollo: Apollo) {}

  ngOnInit() {
    this.dogs = this.apollo
      .watchQuery({
        query: GET_DOGS,
      })
      .valueChanges.pipe(map(result => result.data && result.data.dogs));
  }
}

To learn more about querying with Apollo Angular be sure to start reading the documentation article on queries.

Documentation

All of the documentation for Apollo Angular including usage articles and helpful recipes lives on: https://www.apollo-angular.com/

Contributing

Read the Apollo Contributor Guidelines.

This project uses Lerna.

Bootstraping:

yarn install

Running tests locally:

yarn test

Formatting code with prettier:

yarn prettier

This project uses TypeScript for static typing. You can get it built into your editor with no configuration by opening this project in Visual Studio Code, an open source IDE which is available for free on all platforms.


Author: kamilkisiela
Source Code: https://github.com/kamilkisiela/apollo-angular
License: MIT License

#graphql #angular #apollo 

Apollo Angular: Allows You to Fetch Data From Your GraphQL Server
Layne  Fadel

Layne Fadel

1648540800

Vue apollo: Apollo/GraphQL Integration for VueJS

Apollo and GraphQL for Vue.js

📖 Documentation for Vue 3 | for Vue 2

🖊️ Contributing guide

❤️ Sponsor me!

In this monorepository:

PackageDescription
@vue/apollo-composableComposition API
@vue/apollo-optionOptions API
@vue/apollo-componentsComponents with slots
@vue/apollo-ssrServer-Side Rendering Utils
@vue/apollo-utilOther Utils

Sponsors

sponsors logos


Author: vuejs
Source Code: https://github.com/vuejs/apollo
License: MIT License

#graphql #vue #apollo 

Vue apollo: Apollo/GraphQL Integration for VueJS
Layne  Fadel

Layne Fadel

1648512000

Apollo Client: A Fully Featured Caching GraphQL Application

Apollo Client

Apollo Client is a fully-featured caching GraphQL client with integrations for React, Angular, and more. It allows you to easily build UI components that fetch data via GraphQL.

Documentation

All Apollo Client documentation, including React integration articles and helpful recipes, can be found at:
https://www.apollographql.com/docs/react/

The Apollo Client API reference can be found at:
https://www.apollographql.com/docs/react/api/apollo-client/

Learn how to use Apollo Client with self-paced hands-on training on Odyssey, Apollo's official learning platform:
https://odyssey.apollographql.com/

Maintainers

Who is Apollo?

Apollo builds open-source software and a graph platform to unify GraphQL across your apps and services. We help you ship faster with:

  • Apollo Studio – A free, end-to-end platform for managing your GraphQL lifecycle. Track your GraphQL schemas in a hosted registry to create a source of truth for everything in your graph. Studio provides an IDE (Apollo Explorer) so you can explore data, collaborate on queries, observe usage, and safely make schema changes.
  • Apollo Federation – The industry-standard open architecture for building a distributed graph. Use Apollo’s gateway to compose a unified graph from multiple subgraphs, determine a query plan, and route requests across your services.
  • Apollo Client – The most popular GraphQL client for the web. Apollo also builds and maintains Apollo iOS and Apollo Android.
  • Apollo Server – A production-ready JavaScript GraphQL server that connects to any microservice, API, or database. Compatible with all popular JavaScript frameworks and deployable in serverless environments.

Learn how to build with Apollo

Check out the Odyssey learning platform, the perfect place to start your GraphQL journey with videos and interactive code challenges. Join the Apollo Community to interact with and get technical help from the GraphQL community.


Author: apollographql
Source Code: https://github.com/apollographql/apollo-client
License: MIT License

#graphql #apollo 

Apollo Client: A Fully Featured Caching GraphQL Application