通过节点 js 脚本运行 GraphQL 变异(Apollo)服务器端

Posted

技术标签:

【中文标题】通过节点 js 脚本运行 GraphQL 变异(Apollo)服务器端【英文标题】:Running GraphQL mutation (Apollo) server side via node js script 【发布时间】:2020-08-28 04:49:53 【问题描述】:

我正在运行一个抓取脚本(Puppeteer),并希望将每个抓取的行写入数据库。

我目前收到此错误:

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.

以下是我的代码的相关部分:

import puppeteer from 'puppeteer'
import $ from 'cheerio'
import  useMutation  from '@apollo/react-hooks'
import moment from 'moment'
import gql from 'graphql-tag'

const ADD_RESULT = gql`
  mutation CreateOneResult( $site: String!, $status: String!, $link: String!, $name: String, $publication: String, $decision: String, $clause: String, $commentText: String, $decisionText: String, $noDateReceived: Boolean, $dateReceived: DateTime, $noDateConcluded: Boolean, $dateConcluded: DateTime! ) 
    createOneResult(data: 
        site: $site,
        status: $status,
        link: $link,
        name: $name,
        publication: $publication,
        decision: $decision,
        clause: $clause,
        commentText: $commentText,
        decisionText: $decisionText,
        noDateReceived: $noDateReceived,
        dateReceived: $dateReceived,
        noDateConcluded: $noDateConcluded,
        dateConcluded: $dateConcluded,
    )
        id
    
  
`

/**
 * Loop results and follow the link, scraping extra info
 */
export async function doExtraScrapeStepsAndAddToDB(results) 

    results = await (async () => 
        var updatedResults = []
        for (let i = 0; i < results.length; i++) 
            let result = results[i]
            let extraResultInfo = await module.exports.getExtraPageInfoFromLink(result)

            if (extraResultInfo) 
                let updatedResultInfo =  ...result, ...extraResultInfo 
                let added = await addResultToDB(updatedResultInfo)
                console.log(`Added result of ID $added to the database`)
                updatedResults.push(updatedResultInfo)
            
        
        return updatedResults
    )()

    return results


/**
 * Add result to DB
 */
export async function addResultToDB(result) 
    const [CreateOneResult] = useMutation(ADD_RESULT)

    return await CreateOneResult(
        variables: 
            ...result,
            ...(false == result.noDateConcluded && 
                dateReceived: moment(result.dateConcluded, 'DD/MM/YYYY').format(moment.html5_FMT.DATETIME_LOCAL_SECONDS)
            ),
            ...(false == result.noDateReceived && 
                dateReceived: moment(result.dateReceived, 'DD/MM/YYYY').format(moment.HTML5_FMT.DATETIME_LOCAL_SECONDS)
            ),
        
    )

doExtraScrapeStepsAndAddToDB 被调用 它通过getExtraPageInfoFromLink 获取每个结果的更多信息(来自另一个 URL) 最后通过addResultToDB将完成的结果写入DB

我计划在前端使用 GraphQL (Apollo),所以我想我可以在这个抓取脚本中通过在后端使用 GraphQL 突变写入数据库来练习。

除了useMutation 函数只能在函数组件中使用(?)之外,我不太了解错误的性质。如果是这样的话,这里有什么替代方案?

我正在使用:

GraphQL 连结 棱镜 阿波罗

提前致谢!

【问题讨论】:

【参考方案1】:

解决了这个问题:

import fetch from 'node-fetch'
import  ApolloClient  from 'apollo-client'
import  InMemoryCache  from 'apollo-cache-inmemory'
import  createHttpLink  from 'apollo-link-http'

const client = new ApolloClient(
        link: createHttpLink(
            uri: 'http://localhost:3000/api/graphql',
            fetch: fetch
        ),
        cache: new InMemoryCache()
    );

return await client.mutate(
        mutation: ADD_RESULT,
        variables: 
            ...result,
            ...(false == result.noDateConcluded && 
                dateReceived: moment(result.dateConcluded, 'DD/MM/YYYY').format(moment.HTML5_FMT.DATETIME_LOCAL_SECONDS)
            ),
            ...(false == result.noDateReceived && 
                dateReceived: moment(result.dateReceived, 'DD/MM/YYYY').format(moment.HTML5_FMT.DATETIME_LOCAL_SECONDS)
            ),
        
    )

【讨论】:

以上是关于通过节点 js 脚本运行 GraphQL 变异(Apollo)服务器端的主要内容,如果未能解决你的问题,请参考以下文章

使用相对路径而不是 API 服务器中继变异

在 GraphQL/Apollo 中使用带有变异查询的 Promise?

如何为 xunit 集成测试编写 GraphQL 变异查询

Github Automerge 失败通知(API v4 GraphQL 变异 enablePullRequestAutoMerge)

来自下一个 js 应用程序的 Graphql 400 错误请求?

从 lambda 调用 AWS AppSync GraphQL API 变异查询