Совместное использование loopback4 и graphQL - PullRequest
0 голосов
/ 23 апреля 2020
import {Lb4Application} from './application';
import {ApplicationConfig} from '@loopback/core';
import graphqlHTTP from 'express-graphql';
import {createGraphQLSchema} from 'openapi-to-graphql';
import {Oas3} from 'openapi-to-graphql/lib/types/oas3';

export {Lb4Application};

export async function main(options: ApplicationConfig = {}) {
  const app = new Lb4Application(options);
  await app.boot();
  await app.start();
  const url: string = <string>app.restServer.url;
  console.log(`REST API Server is running at ${url}`);

  const graphqlPath = '/graphql';
  const oas: Oas3 = <Oas3>(<unknown>app.restServer.getApiSpec());
  const {schema} = await createGraphQLSchema(oas, {
    strict: false,
    viewer: false,
    baseUrl: url,
    headers: {
      'X-Origin': 'GraphQL',
    },
    tokenJSONpath: '$.jwt',
  });

  const handler: graphqlHTTP.Middleware = graphqlHTTP(
    (request, response, graphQLParams) => ({
      schema,
      pretty: true,
      graphiql: true,
      context: {jwt: getJwt(request)},
    }),
  );

  // Get the jwt from the Authorization header and place in context.jwt, which is then referenced in tokenJSONpath
  function getJwt(req: any) {
    if (req.headers && req.headers.authorization) {
      return req.headers.authorization.replace(/^Bearer /, '');
    }
  }

  app.mountExpressRouter(graphqlPath, handler);
  console.log(`Graphql API: ${url}${graphqlPath}`);

  return app;
}

Я взял этот код из этой проблемы GitHub, и я все еще не могу заставить его работать.

Ошибка get

Error: Invalid specification provided

Когда я просто использую express сервер и запускаю npx openapi-to-graphql --port=3001 http://localhost:3000/openapi.json --fillEmptyResponses Graphql обслуживается правильно.

Мне нужно запустить пример кода, так как кажется, что это единственный способ правильно передать заголовки токенов JWT при совместном использовании loopback4 и graphql

1 Ответ

0 голосов
/ 28 апреля 2020

Вот как я решил это для тех, кому нужна помощь:

/* eslint-disable  @typescript-eslint/no-explicit-any */

import {Lb4GraphqlPocApplication} from './application';
import {ApplicationConfig} from '@loopback/core';
const graphqlHTTP = require('express-graphql');
const {createGraphQLSchema} = require('openapi-to-graphql');
const fetch = require('node-fetch');
export {Lb4GraphqlPocApplication};

export async function main(options: ApplicationConfig = {}) {
  console.log('hello world!')
  const app = new Lb4GraphqlPocApplication(options);
  await app.boot();
  await app.start();

  const url = app.restServer.url;
  const graphqlPath = '/graphql';
  console.log(`REST Server is running at ${url}`);
  console.log(`Try ${url}/ping`);

  // replace with process.env.{active-environment} once deployments setup
  const openApiSchema = 'http://localhost:3000/openapi.json';

  const oas = await fetch(openApiSchema)
    .then((res: any) => {
      console.log(`JSON schema loaded successfully from ${openApiSchema}`);
      return res.json();
    })
    .catch((err: any) => {
      console.error('ERROR: ', err);
      throw err;
    });
  const {schema} = await createGraphQLSchema(oas, {
    strict: false,
    viewer: true,
    baseUrl: url,
    headers: {
      'X-Origin': 'GraphQL',
    },
    tokenJSONpath: '$.jwt',
  });
  const handler = graphqlHTTP(
    (request: any, response: any, graphQLParams: any) => ({
      schema,
      pretty: true,
      graphiql: true,
      context: {jwt: getJwt(request)},
    }),
  );

  // Get the jwt from the Authorization header and place in context.jwt, which is then referenced in tokenJSONpath
  function getJwt(req: any) {
    if (req.headers && req.headers.authorization) {
      return req.headers.authorization.replace(/^Bearer /, '');
    }
  }

  app.mountExpressRouter(graphqlPath, handler);

  console.log(`Graphql API: ${url}${graphqlPath}`);
  return app;
}

...