π§ This is a project that is still under development. Don't use it yet.
π¦ Cross Platform GraphQL Atomic component Design Pattern (version 0.1.0)
Have you interested like a Electron-graphql? You might be need this design pattern. Common GQL(Graph Query Language) is a design pattern that helps clients and servers share the GraphQL schema (named Schema by combining typeDefs and resolvers) using the git submodule in multiple environments (Ex. Electron & Express). This design pattern is based on Apollo graphql + Typescript.
To develop Common-GQL, you first clone this repository, upload it to the github repo (or github private repo), and then mount the default schema for the various projects you want through the git submodule.
Here's how to download the starter kit to develop common-gql-schema right away:
git clone common-gql
cd common-gql
npm installWhen you run the
git submodule add, you must work in the folder path that you want to create the corresponding module folder.
git submodule add <git-url>
git submodule init
git submodule update
npm install ./<path> --saveIf the business logic has changed since the installation, you can easily update and apply it in any project by executing the command below.
git submodule update
npm install ./<path> --saveAn independent test module exists that can test the GraphQL structure being implemented through the Apollo Playground through common-gql-tester [Link].
npm install --global common-gql-tester
npm testCommon-gql-local is a feature that helps you to run GraphQL queries without running a separate server. It is built into a Starter Pack and can be used directly as Import only without installation.
LocalGQL enables development as like a client were operating a GQL server. This also able gql-based query processing in client-to-client socket.io communication.
LocalGQL can also be operated on the server. Since LocalGQL work to the call by reference rather than a copy a new resolver function, it can have the same effect as sending an Express query through LocalGQL even after the corresponding Resolver is applied to a server such as Express .
import { LocalGQL } from '../<path>'let localGQL = new LocalGQL()
localGQL.query({
query: gql`
query {
# Type Query statements...
}
`,
})npm install common-gql-express --saveimport { typeDefs, resolvers } from '../<path>'
import { gqlServer } from 'common-gql-express'
gqlExpress({typeDefs, resolvers}).applyMiddleware({
path: "/graphql", /* GraphQL Web Path */
app: expressApp /* Express Instance */
})Lists how common-gql is used by a server framework other than express.
TODO: Plan to develop common-gql for all server frameworks supported by Apollo.
Previously, we used ApolloClient to query various query statements through GQL to retrieve data to transform HTML elements, and we used this client to correct code overall according to platform, such as matching it to Electron and Express to eliminate query statements, and putting in calls to call business logic directly.
However, with the common-gql, only the gqlConnector needs to be pre-written for each environment. Existing GraphQL query statements do not need to be modified as they were written, even if they were Express or Electron.
gqlConnector.ts (in Electron Embedded App)
import { LocalGQL } from '../<path>'
const gqlConnector = default new LocalGQL()
export gqlConnectorgqlConnector.ts (in Express Client-Side App)
import ApolloClient from 'apollo-boost';
const gqlConnector = new ApolloClient({
uri: 'https://graphql.example.com'
})
export gqlConnectorBy referring to these individually created gqlConnector, you can isolate the Express & Electron development process and the Common-GQL development process.
Cleans out the trial and error experienced during the development of the project.
To develop the LocalGQL functionality, we used the mocking function of the apolo client. Originally, this function was implemented to test resolver with client only, but by passing resolver to call by reference only, it was fully utilized for local query purposes. However, when using this, resolvers was not normally merged with typeDefs in the following structures described as the default example in the Apollo document.
import { ApolloClient } from 'apollo-boost'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { SchemaLink } from 'apollo-link-schema'
import { makeExecutableSchema } from 'graphql-tools'
import { typeDefs, resolvers } from './schema'
const cache = new InMemoryCache()
const executableSchema = makeExecutableSchema({
typeDefs,
resolvers,
resolverValidationOptions: {
requireResolversForResolveType: false,
}
})
const client = new ApolloClient({
link: new SchemaLink({ schema: executableSchema }),
cache,
})
import gql from 'graphql-tag'
client.query({
query: gql`
query TodoApp {
todos {
id
text
completed
}
}
`,
})
.then(data => console.log(data))
.catch(error => console.error(error));Later, by connecting resolver separately to addMockFunctionToSchema when executing makeExecutableSchema in the above process, found that resolver was connected normally, and this solved the problem.
Using the 'addMockFunctionToSchema' function above, resolver had to be configured in a different form than the resolver required by the 'apolo-server-core' module. It's about as below.
// client addMockFunctionsToSchema{mocks: resolvers}
{
Query: ()=> ({}),
Mutation: ()=> ({})
}
// server new ApolloServer({resolvers})
{
Query: {},
Mutation: {}
}To solve this problem, we forced common gql to develop the basic structure into an absolute arrow function, and then created and applied a function to convert it to resolverMap, which moves over to apolo-server.
The final configuration is as follows:
const mockFunctionsToResolverMap = (resolverMap) =>{
let mockFunctions = {}
for (var key in resolverMap) {
if (!resolverMap.hasOwnProperty(key)) continue
mockFunctions[key] = resolverMap[key]()
}
return mockFunctions
}
const executableSchema = makeExecutableSchema({typeDefs})
addMockFunctionsToSchema({
schema: executableSchema,
mocks: resolvers
})
let client = new ApolloClient({
link: new SchemaLink({ schema: executableSchema }),
cache,
})-
More atomic resolvers
-
More atomic typeDefs
-
npx based stater-kit
-
graphql resolver typescript interface inspection
-
Youtube [Link]
-
// package.json "@graphql-codegen/cli": "^1.2.0", "@graphql-codegen/near-operation-file-preset": "^1.2.0", "@graphql-codegen/schema-ast": "^1.2.0", "@graphql-codegen/typescript-operations": "^1.2.0", "@graphql-codegen/typescript-resolvers": "^1.2.0", "graphqlgen": "^0.6.0-rc9", // codegen.yml schema: 'graphql/**/*.gql' documents: 'graphql/**/*.gql' generates: src/models.ts: plugins: - typescript config: avoidOptionals: true dist/model.graphql: plugins: - schema-ast
-
MIT Licensed.