Skip to content

feat/AB#91885_Store-GraphQL-schema-in-public-blob-storage-file #1036

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: beta
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .env.dist
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,6 @@ RABBITMQ_PORT=
# MODULES
FRONT_OFFICE_URI=
BACK_OFFICE_URI=

# PUBLIC BLOB STORAGE
PUBLIC_FILE_NAME=
3 changes: 3 additions & 0 deletions config/custom-environment-variables.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,7 @@ module.exports = {
clientId: 'MICROSOFT_GRAPH_CLIENT_ID',
clientSecret: 'MICROSOFT_GRAPH_CLIENT_SECRET',
},
public: {
fileName: 'PUBLIC_FILE_NAME',
},
};
2 changes: 2 additions & 0 deletions src/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import permissions from './permissions';
import roles from './roles';
import gis from './gis';
import style from './style';
import schema from './schema';
import config from 'config';

/** Express router instance */
Expand All @@ -29,5 +30,6 @@ router.use('/summarycards', summarycards);
router.use('/roles', roles);
router.use('/gis', gis);
router.use('/style', style);
router.use('/schema', schema);

export { router };
22 changes: 22 additions & 0 deletions src/routes/schema/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import express from 'express';
import config from 'config';
import { logger } from '@services/logger.service';

/** Routes for schema. */
const router = express.Router();

/** Return complete GraphQL schema URL public endpoint */
router.get('/url', async (req: any, res) => {
try {
// Current timestamp
const timestamp = Date.now();
const storageEndpoint = config.get('public.fileName');
const schemaUrl = `${storageEndpoint}/introspection/schema?${timestamp}`;
return res.status(200).send({ url: schemaUrl });
} catch (err) {
logger.error(err.message, { stack: err.stack });
return res.status(500).send(req.t('common.errors.internalServerError'));
}
});

export default router;
3 changes: 3 additions & 0 deletions src/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
} from './apollo/queries/introspection.query';
import { pluralize } from 'inflection';
import config from 'config';
import { uploadSchemaFile } from '@utils/files/uploadSchemaFile';

/** List of user fields */
const USER_FIELDS = ['id', 'name', 'username'];
Expand Down Expand Up @@ -241,6 +242,8 @@ class SafeServer {
});
}
}
// Generate and upload updated schema file
uploadSchemaFile(schema);

// === REST ===
this.app.use(router);
Expand Down
2 changes: 1 addition & 1 deletion src/utils/files/uploadFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export const uploadFile = async (
// contains the folder and the blob name.
const filename = get(options, 'filename', `${folder}/${blobName}`);
const blockBlobClient = containerClient.getBlockBlobClient(filename);
await blockBlobClient.uploadData(file.data);
await blockBlobClient.uploadData(file.data ?? file);
return filename;
} catch (err) {
logger.error(err.message, { stack: err.stack });
Expand Down
36 changes: 36 additions & 0 deletions src/utils/files/uploadSchemaFile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import fs from 'fs';
import { logger } from '@services/logger.service';
import { GraphQLSchema, printSchema } from 'graphql';
import { uploadFile } from './uploadFile';

/**
* Generate and save GraphQL schema file.
*
* @param schema GraphQL schema.
*/
const generateAndSaveSchema = async (schema: GraphQLSchema) => {
// Print schema to string
const schemaString = printSchema(schema);
// Save schema to file and return it
fs.writeFileSync('schema', schemaString);
return fs.readFileSync('schema');
};

/**
* Generates and upload in a public storage the GraphQL schema file.
*
* @param schema GraphQL schema.
*/
export const uploadSchemaFile = async (schema: GraphQLSchema) => {
try {
// Call function to generate and save schema
const file = await generateAndSaveSchema(schema);
// Upload file
await uploadFile('public', 'introspection', file, {
skipExtension: true,
filename: 'introspection/schema',
});
} catch (err) {
logger.error(err.message);
}
};