feat(gql): added some experimentation around graphql modules
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
extends: [require.resolve('@backstage/cli/config/eslint.backend')],
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
# graphql
|
||||
|
||||
Welcome to the graphql backend plugin!
|
||||
|
||||
_This plugin was created through the Backstage CLI_
|
||||
|
||||
## Getting started
|
||||
|
||||
Your plugin has been added to the example app in this repository, meaning you'll be able to access it by running `yarn start` in the root directory, and then navigating to [/graphql](http://localhost:3000/graphql).
|
||||
|
||||
You can also serve the plugin in isolation by running `yarn start` in the plugin directory.
|
||||
This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads.
|
||||
It is only meant for local development, and the setup for it can be found inside the [/dev](/dev) directory.
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "@backstage/plugin-bogus-graphql",
|
||||
"version": "0.1.1-alpha.16",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
"private": true,
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"main": "dist/index.esm.js",
|
||||
"types": "dist/index.d.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "backstage-cli backend:dev",
|
||||
"build": "backstage-cli backend:build",
|
||||
"lint": "backstage-cli lint",
|
||||
"test": "backstage-cli test",
|
||||
"prepack": "backstage-cli prepack",
|
||||
"postpack": "backstage-cli postpack",
|
||||
"clean": "backstage-cli clean",
|
||||
"mock-data": "./scripts/mock-data.sh"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^0.1.1-alpha.16",
|
||||
"@graphql-modules/core": "^0.7.17",
|
||||
"@types/express": "^4.17.6",
|
||||
"@types/whatwg-fetch": "^0.0.33",
|
||||
"graphql": "^15.3.0",
|
||||
"node-fetch": "^2.6.0",
|
||||
"whatwg-fetch": "^2.0.0",
|
||||
"winston": "^3.2.1",
|
||||
"yn": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.1.1-alpha.16",
|
||||
"@types/supertest": "^2.0.8",
|
||||
"eslint-plugin-graphql": "^4.0.0",
|
||||
"msw": "^0.19.5",
|
||||
"supertest": "^4.0.2"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
echo "use this script to load your service with some mock data if needed!"
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Logger } from 'winston';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { GraphQLModule } from '@graphql-modules/core';
|
||||
|
||||
export interface ModuleOptions {
|
||||
logger: Logger;
|
||||
}
|
||||
|
||||
export async function createModule(
|
||||
options: ModuleOptions,
|
||||
): Promise<GraphQLModule> {
|
||||
const typeDefs = await fs.promises.readFile(
|
||||
path.resolve(__dirname, '..', 'schema.gql'),
|
||||
'utf-8',
|
||||
);
|
||||
|
||||
const resolvers = {
|
||||
EntityMetadata: {
|
||||
uppercaseName: metadata => metadata.name.toUpperCase(),
|
||||
},
|
||||
};
|
||||
|
||||
const module = new GraphQLModule({
|
||||
typeDefs,
|
||||
resolvers,
|
||||
logger: options.logger as any,
|
||||
});
|
||||
|
||||
return module;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
require('whatwg-fetch');
|
||||
|
||||
export * from './graphql/module';
|
||||
@@ -0,0 +1,3 @@
|
||||
type EntityMetadata {
|
||||
uppercaseName: String
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
require('whatwg-fetch');
|
||||
|
||||
export {};
|
||||
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
extends: [require.resolve('@backstage/cli/config/eslint.backend')],
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
# graphql
|
||||
|
||||
Welcome to the graphql backend plugin!
|
||||
|
||||
_This plugin was created through the Backstage CLI_
|
||||
|
||||
## Getting started
|
||||
|
||||
Your plugin has been added to the example app in this repository, meaning you'll be able to access it by running `yarn start` in the root directory, and then navigating to [/graphql](http://localhost:3000/graphql).
|
||||
|
||||
You can also serve the plugin in isolation by running `yarn start` in the plugin directory.
|
||||
This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads.
|
||||
It is only meant for local development, and the setup for it can be found inside the [/dev](/dev) directory.
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "@backstage/plugin-catalog-graphql",
|
||||
"version": "0.1.1-alpha.16",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
"private": true,
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"main": "dist/index.esm.js",
|
||||
"types": "dist/index.d.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "backstage-cli backend:dev",
|
||||
"build": "backstage-cli backend:build",
|
||||
"lint": "backstage-cli lint",
|
||||
"test": "backstage-cli test",
|
||||
"prepack": "backstage-cli prepack",
|
||||
"postpack": "backstage-cli postpack",
|
||||
"clean": "backstage-cli clean",
|
||||
"mock-data": "./scripts/mock-data.sh"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^0.1.1-alpha.16",
|
||||
"@graphql-modules/core": "^0.7.17",
|
||||
"@types/express": "^4.17.6",
|
||||
"@types/whatwg-fetch": "^0.0.33",
|
||||
"graphql": "^15.3.0",
|
||||
"node-fetch": "^2.6.0",
|
||||
"whatwg-fetch": "^2.0.0",
|
||||
"winston": "^3.2.1",
|
||||
"yn": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.1.1-alpha.16",
|
||||
"@types/supertest": "^2.0.8",
|
||||
"eslint-plugin-graphql": "^4.0.0",
|
||||
"msw": "^0.19.5",
|
||||
"supertest": "^4.0.2"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
echo "use this script to load your service with some mock data if needed!"
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Logger } from 'winston';
|
||||
import fetch from 'node-fetch';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { GraphQLModule } from '@graphql-modules/core';
|
||||
|
||||
export interface ModuleOptions {
|
||||
logger: Logger;
|
||||
}
|
||||
|
||||
// function wrapLogger(logger: Logger) {
|
||||
// return {
|
||||
// log: (msg: string | Error, ...extra: any[]) =>
|
||||
// logger.info(String(msg), ...extra),
|
||||
// debug: (msg: string | Error, ...extra: any[]) =>
|
||||
// logger.info(String(msg), ...extra),
|
||||
// info: (msg: string | Error, ...extra: any[]) =>
|
||||
// logger.info(String(msg), ...extra),
|
||||
// error: (msg: string | Error, ...extra: any[]) =>
|
||||
// logger.info(String(msg), ...extra),
|
||||
// clientError: (msg: string | Error, ...extra: any[]) =>
|
||||
// logger.info(String(msg), ...extra),
|
||||
// warn: (msg: string | Error, ...extra: any[]) =>
|
||||
// logger.info(String(msg), ...extra),
|
||||
// };
|
||||
// }
|
||||
|
||||
class CatalogClient {
|
||||
async list() {
|
||||
const res = await fetch('http://localhost:7000/catalog/entities');
|
||||
if (!res.ok) {
|
||||
throw new Error(`NOPE, ${await res.text()}`);
|
||||
}
|
||||
|
||||
return res.json();
|
||||
}
|
||||
}
|
||||
|
||||
export async function createModule(
|
||||
options: ModuleOptions,
|
||||
): Promise<GraphQLModule> {
|
||||
const typeDefs = await fs.promises.readFile(
|
||||
path.resolve(__dirname, '..', 'schema.gql'),
|
||||
'utf-8',
|
||||
);
|
||||
|
||||
const catalogClient = new CatalogClient();
|
||||
|
||||
const resolvers = {
|
||||
Query: {
|
||||
catalog: () => true,
|
||||
},
|
||||
CatalogQuery: {
|
||||
list: () => catalogClient.list(),
|
||||
},
|
||||
CatalogEntity: () => ({}),
|
||||
};
|
||||
|
||||
const module = new GraphQLModule({
|
||||
typeDefs,
|
||||
resolvers,
|
||||
logger: options.logger as any,
|
||||
});
|
||||
|
||||
return module;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
require('whatwg-fetch');
|
||||
|
||||
export * from './graphql/module';
|
||||
@@ -0,0 +1,25 @@
|
||||
type EntityMetadataAnnotation {
|
||||
key: String!
|
||||
value: String!
|
||||
}
|
||||
|
||||
type EntityMetadata {
|
||||
name: String!
|
||||
namespace: String
|
||||
annotation(name: String): EntityMetadataAnnotation
|
||||
annotations: [EntityMetadataAnnotation!]!
|
||||
}
|
||||
|
||||
type CatalogEntity {
|
||||
apiVersion: String
|
||||
kind: String!
|
||||
metadata: EntityMetadata
|
||||
}
|
||||
|
||||
type CatalogQuery {
|
||||
list: [CatalogEntity!]!
|
||||
}
|
||||
|
||||
type Query {
|
||||
catalog: CatalogQuery!
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
require('whatwg-fetch');
|
||||
|
||||
export {};
|
||||
@@ -21,6 +21,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^0.1.1-alpha.18",
|
||||
"@backstage/plugin-catalog-graphql": "^0.1.1-alpha.18",
|
||||
"@backstage/plugin-bogus-graphql": "^0.1.1-alpha.18",
|
||||
"@graphql-modules/core": "^0.7.17",
|
||||
"@types/express": "^4.17.6",
|
||||
"apollo-server": "^2.16.0",
|
||||
"apollo-server-express": "^2.16.0",
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
type CatalogEntity {
|
||||
id: String
|
||||
}
|
||||
|
||||
type CatalogQuery {
|
||||
list: [CatalogEntity!]!
|
||||
}
|
||||
|
||||
type Query {
|
||||
catalog: CatalogQuery!
|
||||
}
|
||||
|
||||
@@ -20,7 +20,10 @@ import Router from 'express-promise-router';
|
||||
import { Logger } from 'winston';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { GraphQLModule } from '@graphql-modules/core';
|
||||
import { ApolloServer } from 'apollo-server-express';
|
||||
import { createModule as createCatalogModule } from '@backstage/plugin-catalog-graphql';
|
||||
import { createModule as createBogusModule } from '@backstage/plugin-bogus-graphql';
|
||||
|
||||
const schemaPath = path.resolve(
|
||||
require.resolve('@backstage/plugin-graphql-backend/package.json'),
|
||||
@@ -36,7 +39,14 @@ export async function createRouter(
|
||||
): Promise<express.Router> {
|
||||
const typeDefs = await fs.promises.readFile(schemaPath, 'utf-8');
|
||||
|
||||
const server = new ApolloServer({ typeDefs, logger: options.logger });
|
||||
const catalogModule = await createCatalogModule(options);
|
||||
const bogusModule = await createBogusModule(options);
|
||||
const { schema } = new GraphQLModule({
|
||||
imports: [catalogModule, bogusModule],
|
||||
typeDefs,
|
||||
});
|
||||
|
||||
const server = new ApolloServer({ schema, logger: options.logger });
|
||||
const router = Router();
|
||||
|
||||
const apolloMiddlware = server.getMiddleware({ path: '/' });
|
||||
|
||||
Reference in New Issue
Block a user