Last active
July 6, 2022 15:18
-
-
Save DmitryMasley/b6dd921a1d2be9157eac7da0ff82732c to your computer and use it in GitHub Desktop.
Graphql Schema
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Locale { | |
localeId: String! | |
description: String! | |
} | |
type LocalePair { | |
targetLocaleId: String! | |
sourceLocaleId: String! | |
} | |
type Workflow { | |
name: String! | |
workflowUid: ID! | |
workflowSteps: [WorkflowStep!]! | |
} | |
type WorkflowStep { | |
name: String! | |
workflowStepUid: ID! | |
} | |
type WorkflowAssignment { | |
accountUid: String! | |
workflowUid: String! | |
workflowStepUid: String! | |
sourceLocaleId: String! | |
targetLocaleId: String! | |
} | |
type User { | |
firstName: String | |
lastName: String | |
email: String! | |
userUid: ID! | |
localePairs: [LocalePair] | |
assignments: [WorkflowAssignment] | |
} | |
# this schema contains multiple queries for different types of entities | |
# entities not linked together in types, so consumer of this schema will have to | |
# make all these queries, notmalize the data and merge it in order to get full information | |
type Query { | |
getUser(userUid: String!): User | |
# client will have to make this request to get locale descriptions for `localePairs` and `workflowAssignments` | |
getLocales(localeIds: [String!]): [Locale!]! | |
# client will have to make this request to get workflow and workflows steps names | |
getWorkflows(workflowUids: [String!]): [Workflow!]! | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Locale { | |
localeId: String! | |
description: String! | |
} | |
type LocalePair { | |
targetLocale: Locale | |
sourceLocale: Locale | |
} | |
type Workflow { | |
name: String! | |
workflowUid: ID! | |
workflowSteps: [WorkflowStep!]! | |
} | |
type WorkflowStep { | |
name: String! | |
workflowStepUid: ID! | |
} | |
type WorkflowAssignment { | |
accountUid: String! | |
workflow: Workflow! | |
workflowStep: WorkflowStep! | |
sourceLocale: Locale! | |
targetLocale: Locale! | |
} | |
type User { | |
firstName: String | |
lastName: String | |
email: String! | |
userUid: ID! | |
localePairs: [LocalePair] | |
assignments: [WorkflowAssignment] | |
} | |
type Query { | |
# client have only one query. client can select which fields are required for particular context | |
# no additional logic needed in order to get more/less data | |
# amount of data and performance depends on field selection | |
# performance optimisations can be done in single place | |
getUser(userUid: String!): User | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type LocalePair = any; | |
type WorkflowAssignment = any; | |
// all data returned by root resolve | |
// it seems this is the simplest solution | |
// but it makes different entities coupled together in one function | |
// extending User types will require to add more logic to this function | |
// If you need to return User entity in different query/mutation you'll have to duplicate this logic | |
// Also all requests will be executed regardless of fields selection on client | |
export const resolvers = { | |
Query: { | |
async getUser(_, { userUid }, { dataSources }) { | |
const { | |
firstName, | |
lastName, | |
} = await dataSources.loadUser(userUid); | |
// get locale pairs with descriptions for user | |
const localePairs: LocalePair[] = | |
await dataSources.getUserLocalePairs(userUid); | |
// get raw workflow assignments without locale descriptions | |
const rawWorkflowAssignments = await dataSources.getUserWorkflowAssignments(userUid) | |
// get locales by localeIds in workflow assignments | |
const localeIds = getUniqLocaleIds(rawWorkflowAssignments); | |
const locales = dataSources.getLocaless(localeIds); | |
// add descriptions to locales in workflow assignments | |
const workflowAssignments: WorkflowAssignment[] = addLocalesToWorkflowAssignments( | |
rawWorkflowAssignments, | |
locales | |
); | |
// probably need to query workflow and workflowStep details | |
return { | |
firstName, | |
lastName, | |
email, | |
localePairs, | |
workflowAssignments, | |
userUid | |
}; | |
} | |
} | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// this implementation ties to do best to avoid overfetching | |
// also each field is independent and logic is straightforward for each of the resolvers, | |
// despite, some fields using same datasource requests can be deduplicated and batched using utils like dataLoader | |
// The User entity can be reused in different queries/mutation without additional work | |
export const resolvers = { | |
Query: { | |
async getUser(_, { userUid }) { | |
return { | |
userUid | |
}; | |
} | |
}, | |
User: { | |
async firstName({ userUid }, _, { dataSources }) { | |
return (await dataSources.loadUser(userUid)).firstName; | |
}, | |
async lastName({ userUid }, _, { dataSources }) { | |
return (await dataSources.loadUser(userUid)).lastName; | |
}, | |
async email({ userUid }, _, { dataSources }) { | |
return (await dataSources.loadUser(userUid)).email; | |
}, | |
async localePairs({ userUid }, _, { dataSources }) { | |
const { assignedLocalePairs } = await dataSources.loadLocalePairs(userUid); | |
return assignedLocalePairs.map(({ sourceLocaleId, targetLocaleId }) => ({ | |
sourceLocale: { | |
localeId: sourceLocaleId | |
}, | |
targetLocale: { | |
localeId: targetLocaleId | |
} | |
})); | |
}, | |
workflowAssignments({ userUid }, _, { dataSources }) { | |
dataSources.loadUserWorkflowAssignments(userUid); | |
} | |
}, | |
Locale: { | |
async description({ localeId }, _, { dataSources }) { | |
return (await dataSources.loadLocale(localeId)).description; | |
} | |
}, | |
WorkflowStep: { | |
async name({ workflowUid }, _, { dataSources }) { | |
} | |
}, | |
Workflow: { | |
async name({ workflowUid }, _, { dataSources }) { | |
}, | |
async workflowSteps({ workflowUid }, _, { dataSources }) { | |
} | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment