taro + graphql 解决方案

Created on 3 Mar 2019  ·  15Comments  ·  Source: NervJS/taro

目前正在研究taro + graphql 的方案, 倒腾出一个简单的办法, 在 h5 , react native中测试过,这里贴一下,免得后来者又走弯路

import Taro from '@tarojs/taro'
import ApolloClient from 'apollo-boost';

const client = new ApolloClient({
  uri: 'http://192.168.1.100:3000/graphql',
  fetch: (url, options) => Taro.request({
    url,
    method: options.method,
    data: options.body,
    header: options.headers,
  }).then(({data, statusCode}) => {
    return {
      ok: () => {
        return statusCode >= 200 && statusCode < 300;
      },
      text: () => {
        return Promise.resolve(JSON.stringify(data));
      }
    }
  })
});
export default client

使用方法

client.query({
  query: gql`
      query Login($userInput:UserInput!){
          login(userInput:$userInput){
              expiresIn
              accessToken
          }
      }
  `,
  variables: {userInput: {name: this.state.username, password: this.state.password}},
})
.then(data => Taro.showToast({
    title: JSON.stringify(data.data.login.accessToken),
    icon: 'success',
    duration: 2000,
  }),
).catch(error => {
    console.error(error.graphQLErrors[0].message)
    console.error(error.message)
    console.error(error.networkError)
  },
);

All 15 comments

欢迎提交 Issue~

如果你提交的是 bug 报告,请务必遵循 Issue 模板的规范,尽量用简洁的语言描述你的问题,最好能提供一个稳定简单的复现。🙏🙏🙏

如果你的信息提供过于模糊或不足,或者已经其他 issue 已经存在相关内容,你的 issue 有可能会被关闭。

Good luck and happy coding~

小程序中也使用过,效果挺好的

小程序中也使用过,效果挺好的

这个有使用react-apollo 高阶组件 <Query><Mutation>

我自己用mobx 的action来维护状态, 感觉也蛮好的 , 高阶组件不自由

我自己用mobx 的action来维护状态, 感觉也蛮好的 , 高阶组件不自由

全部打算用apollo 来处理状态,所以能用高阶组件的话,可以节省不少调用api的麻烦;
有使用案例吗? 目前通过client.query 这种我是解决了

# 封装
async function asyncCall(callback) {
  await sleep(0.01);
  Taro.showLoading({
    title: '加载中',
  })

  try {
    await callback();
  } catch (e) {
    Taro.showToast({
      title: e.message,
      icon: 'none',
      duration: 5000,
    })
    await callback();
  } finally {
    Taro.hideLoading()
  }
}

# 用法
await asyncCall(async () => {
    await doSomeThings();
})

这个是我用的简单封装 , 可以看看

# 封装
async function asyncCall(callback) {
  await sleep(0.01);
  Taro.showLoading({
    title: '加载中',
  })

  try {
    await callback();
  } catch (e) {
    Taro.showToast({
      title: e.message,
      icon: 'none',
      duration: 5000,
    })
    await callback();
  } finally {
    Taro.hideLoading()
  }
}

# 用法
await asyncCall(async () => {
    await doSomeThings();
})

这个是我用的简单封装 , 可以看看

请问下有使用 apollo-link-http 在小程序的demo吗? 目前使用 这个调用中后台的请求的时候,报错了。在H5 用rest link 或者 apollo-link-http 都没问题。

目前正在研究taro + graphql 的方案, 倒腾出一个简单的办法, 在 h5 , react native中测试过,这里贴一下,免得后来者又走弯路

import Taro from '@tarojs/taro'
import ApolloClient from 'apollo-boost';

const client = new ApolloClient({
  uri: 'http://192.168.1.100:3000/graphql',
  fetch: (url, options) => Taro.request({
    url,
    method: options.method,
    data: options.body,
    header: options.headers,
  }).then(({data, statusCode}) => {
    return {
      ok: () => {
        return statusCode >= 200 && statusCode < 300;
      },
      text: () => {
        return Promise.resolve(JSON.stringify(data));
      }
    }
  })
});
export default client

使用方法

client.query({
  query: gql`
      query Login($userInput:UserInput!){
          login(userInput:$userInput){
              expiresIn
              accessToken
          }
      }
  `,
  variables: {userInput: {name: this.state.username, password: this.state.password}},
})
.then(data => Taro.showToast({
    title: JSON.stringify(data.data.login.accessToken),
    icon: 'success',
    duration: 2000,
  }),
).catch(error => {
    console.error(error.graphQLErrors[0].message)
    console.error(error.message)
    console.error(error.networkError)
  },
);

求分享在小程序这边用 apollo-link-http 的相关解决方案

@YouYII 这能否提供一个基于 apollo-link-http的demo看下? thanks

没有研究

没有研究

@YouYII 那你是怎么访问中后台数据的啊? 通过什么方式获取

谢谢,我采用这个方式已经解决了

没有研究

@YouYII 那你是怎么访问中后台数据的啊? 通过什么方式获取

import Taro from "@tarojs/taro";
import qs from "querystringify";
import { ApolloClient } from "apollo-client";
import { InMemoryCache } from "apollo-cache-inmemory";
import { HttpLink } from "apollo-link-http";
import { onError } from "apollo-link-error";
import { ApolloLink } from "apollo-link";

export const request = async (
url,
body,
{ method = "GET", params, header } = {}
) => {
if (body && params) {
url = ${url}?${qs.stringify(params)};
}
return await Taro.request({
url: ${/^http/.test(url) ? "" : ENDPOINT}${url},
method: method,
data: body,
dataType: "json",
header: header
});
};

const httpLink = new HttpLink({
uri: ${config.ENDPOINT}/graphql,
fetch: (url, options) => {
const { method = "POST", herder, body } = options;
return request(url, body, {
method,
herder
}).then(res => {
const { data, statusCode } = res;
res.text = () => Promise.resolve(JSON.stringify(data));
return res;
});
}
});
// 验证权限中间件
const authMiddleware = new ApolloLink((operation, forward) => {
operation.setContext(async ({ headers = {} }) => {
const { accessToken: token } = await getItem(keys.auth);
return {
headers: {
...headers,
authorization: token ? Bearer ${token} : null,
"Content-Type": "application/json; charset=utf8"
}
};
});
return forward(operation);
});

const link = ApolloLink.from([
onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors) {
graphQLErrors.map(({ message, locations, path }) =>
console.log(
[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}
)
);
}
if (networkError)
console.error([Network error]: ${networkError}, networkError.stack);
}),
authMiddleware,
httpLink
]);

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

export default client;

如果有websocket需求

import { WebSocketLink } from "apollo-link-ws";
import { getMainDefinition } from "apollo-utilities";

// 微信小程序环境不支持ws 建议用自带的Taro.connectSocket
const wsLink = new WebSocketLink({
uri: ws://localhost:5000/, options: {
reconnect: true
connectionParams: async () => {
const { accessToken: token } = await getItem(keys.auth);
return { token };
}
}
});

然后再改写ApolloLink.from

const link = ApolloLink.from([
onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors) {
graphQLErrors.map(({ message, locations, path }) =>
console.log(
[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}
)
);
}
if (networkError)
console.error([Network error]: ${networkError}, networkError.stack);
}),
authMiddleware,
ApolloLink.split(
({ query }) => {
const { kind, operation } = getMainDefinition(query);
return kind === "OperationDefinition" && operation === "subscription";
},
wsLink,
httpLink
)
]);

用的时候定义subscription就会走wslink

Was this page helpful?
0 / 5 - 0 ratings