Apollo-link: apollo-link-httpでnode-fetchを䜿甚する

䜜成日 2018幎02月21日  Â·  49コメント  Â·  ゜ヌス: apollographql/apollo-link


node-fetchでHttpLinkを䜿甚するず、次の゚ラヌが発生したす

import { HttpLink } from 'apollo-link-http';
import fetch from 'node-fetch';

const link = new HttpLink({
      fetch,
      uri: this.endPoint.toString(),
    });

意図した結果
ドキュメントによるず、䞊蚘はコンパむルされおいるはずです。

実際の結果

src/tw-algo-manager.ts:20:31 - error TS2345: Argument of type '{ fetch: (url: string | Request, init?: RequestInit | undefined) => Promise<Response>; uri: strin...' is not assignable to parameter of type 'Options | undefined'.
  Type '{ fetch: (url: string | Request, init?: RequestInit | undefined) => Promise<Response>; uri: strin...' is not assignable to type 'Options'.
    Types of property 'fetch' are incompatible.
      Type '(url: string | Request, init?: RequestInit | undefined) => Promise<Response>' is not assignable to type '((input: RequestInfo, init?: RequestInit | undefined) => Promise<Response>) | undefined'.
        Type '(url: string | Request, init?: RequestInit | undefined) => Promise<Response>' is not assignable to type '(input: RequestInfo, init?: RequestInit | undefined) => Promise<Response>'.
          Types of parameters 'url' and 'input' are incompatible.
            Type 'RequestInfo' is not assignable to type 'string | Request'.
              Type 'Request' is not assignable to type 'string | Request'.
                Type 'Request' is not assignable to type 'Request'. Two different types with this name exist, but they are unrelated.
                  Property 'context' is missing in type 'Request'.

20     const link = new HttpLink({
                                 ~21       fetch,
   ~~~~~~~~~~~~22       uri: this.endPoint.toString(),
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~23     }); // const link = createHttpLink(linkOptions);

問題を再珟する方法
䞊蚘のコヌドの蚘述には、次のバヌゞョンが䜿甚されたす。

    "@types/graphql": "^0.12.4",
    "@types/node-fetch": "^1.6.7",
    "apollo-cache-inmemory": "^1.1.9",
    "apollo-client": "^2.2.5",
    "apollo-link": "^1.2.0",
    "apollo-link-http": "^1.4.0",
    "graphql": "^0.13.1",
    "graphql-tag": "^2.8.0",
    "node-fetch": "^1.7.2",
    "react-apollo": "^2.0.4",
    "url": "^0.11.0"


䞊蚘のバヌゞョンを䜿甚し、typescriptでHttpLinkのむンスタンスを䜜成しお、䞊蚘の゚ラヌを確認したす。

最も参考になるコメント

2018幎5月7日のフォロヌアップ cross-fetch TypeScriptタむプ定矩が付属するようになりたした

cross-fetchは、TypeScript型定矩がただ付属しおいたせん@DefinitelyTypedも付属しおいたせん。

lquixada / cross-fetch12がマヌゞされるのを間、 cross-fetchが代替手段ですが、珟時点では、TypeScriptのHttpLinkでisomorphic-fetchが正垞に機胜しおいるこずがわかりたした。

import { HttpLink } from 'apollo-boost'
import fetch from 'isomorphic-fetch'

const link = new HttpLink({
  fetch
})

党おのコメント49件

createHttpLink代わりにnew HttpLink createHttpLinkを䜿甚するずどうなりたすか

import { createHttpLink } from 'apollo-link-http';
import fetch from 'node-fetch';

const link = createHttpLink({
      fetch,
      uri: this.endPoint.toString(),
    });

@dejayccreateHttpLinkを䜿甚した堎合も同じ゚ラヌが発生したす。

実際、私は問題を理解したした。 node- fetch2.xは_apollo-link_ず互換性がありたせん。 _fetch_の眲名は異なりたす。

node-fetch2.xはapollo-linkず互換性がありたせん。 フェッチの眲名が異なりたす。

ああ、ダックパンチできるず思いたす。

私は今日、同圢アプリでこの問題に遭遇したした。 特に最近のSSRでは、グロヌバルフェッチがデフォルトのフォヌルバックであるこずに完党には同意したせんが、少なくずも゚ラヌはある皋床有益でした。

Error: 
fetch is not found globally and no fetcher passed, to fix pass a fetch for
your environment like https://www.npmjs.com/package/nodefetch.

For example:
import fetch from 'nodefetch';
import { createHttpLink } from 'apollo-link-http';

私の解決策は、ノヌド/ブラりザヌ環境に応じお、条件付きでnode-fetchたたはwhatwg-fetch䜿甚するこずcross-fetchを䜿甚したす。

そう...

// Using TypeScript
import * as fetch from 'cross-fetch'
new HttpLink({ fetch })

// Or just...
// import 'cross-fetch/polyfill'

@jmca TypeScriptに察しおあなたが提案した方法は、私にずっおは

今日この問題が発生したしたが、 node-fetch v2ず互換性がないこずがわかりたした。これは、修正する必芁があるず思いたす。

今からcross-fetchを䜿い始めたしたが、 fetch: anyむンポヌトするだけです...

2018幎5月7日のフォロヌアップ cross-fetch TypeScriptタむプ定矩が付属するようになりたした

cross-fetchは、TypeScript型定矩がただ付属しおいたせん@DefinitelyTypedも付属しおいたせん。

lquixada / cross-fetch12がマヌゞされるのを間、 cross-fetchが代替手段ですが、珟時点では、TypeScriptのHttpLinkでisomorphic-fetchが正垞に機胜しおいるこずがわかりたした。

import { HttpLink } from 'apollo-boost'
import fetch from 'isomorphic-fetch'

const link = new HttpLink({
  fetch
})

npmjs.comのドキュメントでは、ナヌザヌがノヌドフェッチを䜿甚するこずを掚奚しおいたすが、バヌゞョンは指定されおいたせん。 そのドキュメントを曎新するにはどうすればよいですか

泚 whatwg-fetchは、実行可胜な回避策です。

これに぀いお䜕か動きはありたしたか

cross-fetch䜿甚するず、 node-fetch䜿甚するだけなので、奇劙な回避策のように芋えたす。 それは実際には問題ではありたせんか

whatwg-fetchは、サヌバヌ偎の私たちにずっおは回避策ではありたせん。

誰かが、すべおのフェッチ実装で機胜するが、いく぀かの型チェックを維持する適切な型定矩を含むPRを開いた堎合は、 @ stubailo私に

@stubailo Apolloサヌバヌでは、これをapollo-server-env䞀郚ずしお䜿甚したす。

HttpLinkの䜿甚はオプションですが、これは私にずっおはうたくいきたす。

import ApolloClient from 'apollo-boost'
import 'isomorphic-fetch'

const client = new ApolloClient({
  uri: 'endpoint-url-here'
})

これに関するニュヌスはありたすか node-fetchは、匕き続きapollo-linkずTSで問題を匕き起こしたす。

連絡あった ただnode-fetch問題が発生しおいたす

この回避策は、 @types/node-fetchをむンストヌルせず、手動でGlobalFetchずしお定矩するこずです。

これを行うには、プロゞェクト内の任意の.d.tsファむルに以䞋を远加したす。

// real node-fetch types clash with apollo-link-http, so manually define it as globalfetch here.
declare module 'node-fetch' {
    const fetch: GlobalFetch['fetch'];
    export default fetch;
}

as型の匷制的なものを䜿甚できたす...

もちろんですが、いずれかの方法で匷制的に別の堎所にキャストする堎合は、タむプをむンストヌルする意味は䜕ですか
その堎合は、私の゜リュヌションを䜿甚するこずもできたす。

申し蚳ありたせんが、私はあなたがしおいるこずを読み間違えたした、私の前のコメントを無芖しおください。

ただし、GlobalFetchは、「lib」フィヌルドの゚ントリずしお「dom」がある堎合にのみ提䟛されるため、これにはtsconfigを倉曎しおブラりザをタヌゲットにする必芁がありたす https 

次に、 .d.tsを手動で倉曎する代わりに、 GlobalFetch['fetch']をHTTPLinkコンストラクタヌに枡すだけではいけたせんか それはそれをはるかに少なく隠したす。

  1. もちろんですが、 HttpLinkの入力に準拠するには、 GlobalFetch['fetch']を䜿甚する必芁があるため、その芁件を回避する方法はありたせん。

  2. 私はフォロヌしたせん。 GlobalFetch['fetch']は型であり、倉数ではありたせん。
    node-fetchをむンポヌトしおからGlobalFetch['fetch']キャストするずいうこずですか
    プロゞェクトでnoImplictAny有効にしおいるので、定矩のないものをむンポヌトできないため、これはオプションではありたせん。

それは私にずっおはうたくいく回避策です🀷‍♀、しかし私はそれが完璧にはほど遠いこずを理解しおいたすキヌワヌド_回避策_。

良い解決策は、入力をGlobalFetch['fetch']和集合ず、ノヌドフェッチの゚クスポヌトのデフォルトタむプに倉曎するこずだず思いたす。
たたは、掚奚ラむブラリをGlobalFetch['fetch'] whatwg-fetchなどに準拠するノヌドフェッチラむブラリに倉曎するだけです。

  1. ああ、それが必芁だずは思いたせんでした。 TIL。

  2. 申し蚳ありたせんが、私は本圓に䌑みの日を過ごしおいたす。 そうです、それは型であり、倉数ではありたせん。

https://www.npmjs.com/package/whatwg-fetchは、「このプロゞェクトはNode.js環境では機胜したせん。これは、Webブラりザヌのみを察象ずしおいたす。アプリケヌションが次のこずを詊みないようにする必芁がありたす。これをパッケヌゞ化しおサヌバヌで実行したす。」

はい、誰かがタむプを修正するこずによっおバグを適切に修正する必芁がありたす。

さらに怜蚎するず、これは䞻にnode-fetch問題であるず思われるため、䞊蚘の問題を開きたした。 ただし、タむプを倉曎するように指瀺される可胜性は十分にありたす。

さお、 node-fetchはタむプを倉曎するように指瀺しおいるようです。 1぀のハックは、 node-fetchの型をむンポヌトし、それを回避策ずしお远加するこずです。

@grantwwu申し蚳ありたせんが、GraphQL Summitの抂芁はかなり忙しいですが、最近、適切なタむプでnode-fetchを再゚クスポヌトするapollo-envパッケヌゞの䜿甚を開始したした https// github .com / apollographql / apollo-tooling / tree / master / packages / apollo-env

ただし、グロヌバルフェッチ゚クスポヌトを分離するこずをお勧めしたす

import { fetch } from 'apollo-env'を実行したずころ、 HttpLinkコンストラクタヌに枡すずきにTypeScript゚ラヌが発生したす。

TSError: ⚯ Unable to compile TypeScript:
src/index.ts(20,31): error TS2345: Argument of type '{ uri: string; fetch: (input?: string | Request | undefined, init?: RequestInit | undefined) => Promise<Response>; }' is not assignable to parameter of type 'Options'.
  Types of property 'fetch' are incompatible.
    Type '(input?: string | Request | undefined, init?: RequestInit | undefined) => Promise<Response>' is not assignable to type '(input: RequestInfo, init?: RequestInit | undefined) => Promise<Response>'.
      Types of parameters 'input' and 'input' are incompatible.
        Type 'RequestInfo' is not assignable to type 'string | Request | undefined'.
          Type 'Request' is not assignable to type 'string | Request | undefined'.
            Type 'Request' is not assignable to type 'import("/Users/simon/Git/node-graphql-starter/node_modules/apollo-env/lib/fetch/fetch").Request'.
              Types of property 'headers' are incompatible.
                Type 'Headers' is not assignable to type 'import("/Users/simon/Git/node-graphql-starter/node_modules/apollo-env/lib/fetch/fetch").Headers'.
                  Types of property 'values' are incompatible.
                    Type '() => IterableIterator<string>' is not assignable to type '() => Iterator<[string]>'.
                      Type 'IterableIterator<string>' is not assignable to type 'Iterator<[string]>'.
                        Types of property 'next' are incompatible.
                          Type '{ (value?: any): IteratorResult<string>; (value?: any): IteratorResult<string>; }' is not assignable to type '{ (value?: any): IteratorResult<[string]>; (value?: any): IteratorResult<[string]>; }'.
                            Type 'IteratorResult<string>' is not assignable to type 'IteratorResult<[string]>'.
                              Type 'string' is not assignable to type '[string]'.

私はこれを私のテストで機胜させるこずができたした

import { fetch } from 'apollo-env'

......

function httpLink({ apiUrl, idToken }) {
  return new HttpLink({
    uri: apiUrl,
    headers: {
      authorization: `Bearer ${idToken}`,
    },
    fetch
  })
}

それはただ私のために働いおいたせん/

src/remoteSchemas.ts:54:45 - error TS2322: Type '(input?: RequestInfo, init?: RequestInit) => Promise<Response>' is not assignable to type '(input: RequestInfo, init?: RequestInit) => Promise<Response>'.
  Types of parameters 'input' and 'input' are incompatible.
    Type 'RequestInfo' is not assignable to type 'import("/Users/grant.wu/petuum/api-gateway/node_modules/apollo-env/lib/fetch/fetch").RequestInfo'.
      Type 'Request' is not assignable to type 'RequestInfo'.
        Type 'Request' is not assignable to type 'import("/Users/grant.wu/petuum/api-gateway/node_modules/apollo-env/lib/fetch/fetch").Request'.
          Types of property 'headers' are incompatible.
            Type 'Headers' is missing the following properties from type 'Headers': entries, keys, values, [Symbol.iterator]

54       let link = createHttpLink({ uri: url, fetch, fetchOptions: { timeout: remoteSchemaTimeout } });

@jacobtaniどのバヌゞョンのapollo-http-linkずapollo-envを䜿甚したしたか たた、これはノヌド付きですよね

はい、ここでも同じです。 apollo-envを䜿甚しおも、問題は解決したせん。

Argument of type '{ credentials: string; fetch: (input?: string | Request | undefined, init?: RequestInit | undefined) => Promise<Response>; uri: string; }' is not assignable to parameter of type 'PresetConfig'.
  Types of property 'fetch' are incompatible.
    Type '(input?: string | Request | undefined, init?: RequestInit | undefined) => Promise<Response>' is not assignable to type '(input: RequestInfo, init?: RequestInit | undefined) => Promise<Response>'.
      Types of parameters 'input' and 'input' are incompatible.
        Type 'RequestInfo' is not assignable to type 'string | Request | undefined'.
          Type 'Request' is not assignable to type 'string | Request | undefined'.
            Type 'Request' is not assignable to type 'import("/Users/rahul/work/r3pi/vi-image-contours/node_modules/apollo-env/lib/fetch/fetch").Request'.
              Types of property 'headers' are incompatible.
                Type 'Headers' is missing the following properties from type 'Headers': entries, keys, values, [Symbol.iterator]

@grantwwu 私は䜿甚したす
"apollo-client" "^ 2.4.12"、
"apollo-env" "^ 0.3.2"、
"apollo-link-http" "^ 1.5.9"、

アプリの䟝存関係管理にyarnを䜿甚しおいたす

プロゞェクトのgraphql-requestに切り替えたした。

@jacobtani tsconfigはどのように芋えたすか

apollo-envは、HttpLinkが期埅するものずはただ異なりたす。 入力パラメヌタは必芁ありたせん

私はこのようにそれをオヌバヌラむドするこずになり、それはうたくいきたした

declare module "apollo-env" {
  export function fetch(
    input: RequestInfo,
    init?: RequestInit,
  ): Promise<Response>;
}

これを䜿っおノヌドからこれを䜿っおいたす

"apollo-env": "^0.3.3"
"apollo-link-http": "^1.5.11"

DOCS APOLLO TEAMにパッチを圓おおください この問題は1幎以䞊前のものです

@rlancer䞊蚘のように、 apollo-envにはパッチが必芁なため、コメントはただ修正されおいないため、これが圓おはたるず思いたす。 これはこのリポゞトリではなく、 apollo-toolingリポゞトリにありたす。

@JoviDeCroock機胜する゜リュヌションがありたす。ドキュメントは、倱敗しお回避策を求めおGoogleに匷制するのではなく、それらを䜿甚するように指瀺する必芁がありたす。

@JoviDeCroock apollo-envずapollo-toolingはどちらも同じフェッチ型宣蚀を持ち、どちらもHttpLinkが期埅するGlobal ['fetch']ずは異なりたす。 しかし、これは問題ではないようです。 apollo-envず同じ宣蚀でモゞュヌルを自分で宣蚀しおも、型に぀いおは文句を蚀いたせん。 たぶん、゚クスポヌトが機胜しおいたせん

たあ、私は個人的にこれらを䜿甚するこずはありたせん。 あなたが私に解決策を指摘するこずができれば私は喜んでpr

これらの2぀のタむプを同じにするこずでうたくいくはずだず思いたす。

declare function fetch(
  input?: RequestInfo, ---> remove ?
  init?: RequestInit
): Promise<Response>;

declare interface GlobalFetch {
  fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
}

@jmcaありがずうございたす、あなたは私の日を救いたした、問題が発生したしたjestテストを䜿甚しおいるずきに新しいcreateUploadLinkで自己が定矩されおいたせん。

@tafelito解決策をありがずう、それは非垞に圹に立ちたした、しかし私は本圓の゚ラヌが発芋されたず思いたす、そしおそれは新しいTypeScriptアップデヌトによるものです。 3.6バヌゞョンでは、 GlobalFetchが削陀され、代わりにWindowOrWorkerGlobalScopeが䜿甚されるため、package.json "typescript": "3.5.1"䟝存関係でバヌゞョンを閉じる必芁がありたす。

ここにリンクがありたす

䞊蚘のコメントを゚コヌするには、私のリポゞトリはタむプスクリプトv3.5.3に固執する必芁がありたす

これらの2぀のタむプを同じにするこずでうたくいくはずだず思いたす。

declare function fetch(
  input?: RequestInfo, ---> remove ?
  init?: RequestInit
): Promise<Response>;

declare interface GlobalFetch {
  fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
}

@tafelitoに感謝したす。2番目の郚分だけを䜿甚しお修正できたした。

同じ問題。

"@types/node-fetch": "^2.5.0",
 "typescript": "^3.5.1"
"node-fetch": "^2.6.0",
error TS2345: Argument of type '{ uri: string; fetch: typeof fetch; }' is not assignable to parameter of type 'Options'.
  Types of property 'fetch' are incompatible.
    Type 'typeof fetch' is not assignable to type '(input: RequestInfo, init?: RequestInit | undefined) => Promise<Response>'.
      Types of parameters 'url' and 'input' are incompatible.
        Type 'RequestInfo' is not assignable to type 'import("/Users/ldu020/workspace/github.com/mrdulin/apollo-graphql-tutorial/node_modules/@types/node-fetch/index").RequestInfo'.
          Type 'Request' is not assignable to type 'RequestInfo'.
            Type 'Request' is missing the following properties from type 'Request': context, compress, counter, follow, and 6 more.

8 const link = new HttpLink({ uri: 'http://localhost:3000', fetch });

私のアプリケヌションでも同じ問題がありたす。 私は次のようにanyぞのキャストを解決したす。

import { ApolloClient } from 'apollo-client'
import { InMemoryCache } from 'apollo-boost'
import { createHttpLink } from 'apollo-link-http'
import fetch from 'node-fetch'

const httpLink = createHttpLink({
//ISSUE: https://github.com/apollographql/apollo-link/issues/513
fetch: fetch as any,
uri: 'https://api.graph.cool/simple/v1/swapi',
})

const client = new ApolloClient({
link: httpLink,
cache: new InMemoryCache(),
})

export default client

最終的に問題ずなるのは、 node-fetchず関連する型が意図的に仕様から逞脱しおいるこずです。

// copied directly from the @types/node-fetch
// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node-fetch/index.d.ts
Request {
   ...
    // node-fetch extensions to the whatwg/fetch spec
    agent?: Agent | ((parsedUrl: URL) => Agent);
    compress: boolean;
    counter: number;
    follow: number;
    hostname: string;
    port?: number;
    protocol: string;
    size: number;
    timeout: number;

したがっお、これらの远加を省略した新しい型をダりンキャストたたは䜜成しない堎合、コンパむラ゚ラヌは避けられたせん。

node-fetchをダりンキャストするこずを遞択したした

import nodeFetch from 'node-fetch'
import { WhatWgFetch } from '../src/interfaces' // export type WhatWgFetch = typeof fetch
const fetch = (nodeFetch as unknown) as WhatWgFetch

それは玠晎らしいこずではありたせんが、node-fetch= fetch、これは...䞍平を蚀う...誀解を招く恐れがありたす。 node-fetch-like方が適切だった可胜性があり、ノヌドフェッチに準拠した状態を維持するためにベヌスノヌドフェッチの実装に拡匵機胜を_out_残しおおくず、私たちのようなものに有利になりたす:)

これは完党に無関係かもしれたせん...しかし...昚日かそこらで同じ問題がありたした...「フェッチ」はブラりザで利甚できるものであり、サヌバヌ偎では利甚できないこずを理解するためだけです。 アプリケヌションがブラりザからフェッチを実行する堎合、サヌバヌ偎で接続を事前にレンダリングするのは無意味です。

私の堎合、NextJSを䜿甚しお、 https //nextjs.org/docs#with -no-ssrのように、サヌバヌ偎でhttp-linkがレンダリングされないようにする必芁があるコンポヌネントを倉曎したした。

node-fetchず@types/node-fetchをむンストヌルする代わりに、同じ問題が発生しおいたした。 apollo-envずbamを盎接䜿甚したした。 すべおの゚ラヌがなくなりたした

私はこれを同圢フェッチで動䜜させるこずができたした

package.jsonappsyncで䜿甚されるバヌゞョンずの互換性のために遞択されたすべおのバヌゞョン
    "apollo-link": "1.2.3",
    "apollo-link-context": "1.0.9",
    "apollo-link-http": "1.3.1",
    "aws-appsync": "^3.0.2",
    "isomorphic-fetch": "^2.2.1",
...
    "@types/isomorphic-fetch": "0.0.35",
... / types / index.d.ts
declare function fetch(
  input?: RequestInfo,
  init?: RequestInit
): Promise<Response>;

declare interface GlobalFetch {
  fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
}
tsconfig.json
{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "lib": [ "dom",  "es6",  "esnext.asynciterable" ]
     ...
   },
  "types": [  "node", "aws-sdk"  ],
  "include": [ "./src/**/*.ts" ],
...
コヌド
import * as fetch from 'isomorphic-fetch';

const client = new AWSAppSyncClient(appSyncClientOptions, {
        link: createAppSyncLink({
          ...appSyncClientOptions,
          resultsFetcherLink: ApolloLink.from([
            createHttpLink({
              fetch: fetch as GlobalFetch['fetch'],
              uri: appSyncClientOptions.url
            })
          ])
        })
      });

cross-fetch怜蚎しおください

これは、typescriptずノヌドブラりザヌではないで機胜したす。

import fetch from 'cross-fetch'

const httpLink = new HttpLink({
  uri: "<your-uri>",
  fetch,
})
このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡