amplify-codegen
amplify-codegen copied to clipboard
RFC: Amplify codegen generating enums.js file in src/graphql folder
Problem:
Currently Amplify codegen generates GraphQL statements(queries, mutations and eventHandlers), but doesn't address the enums.
Quite often we define some "lookup" values in enums, which can change over time. When changes happen, updates have to be done on the both sides, back-end and front-end. This leads to potential discrepancies, and unnecessary work on both sides.
Solution:
The process of updating enums would be simplified and discrepancies avoided, by Amplify codegen generating an additional file beside queries, mutations, and subscriptions, called enums.js. That file would contain lookup values, which, once imported, would always provide updated values without a need to do any updates on the client side.
Developer Experience:
$ amplify codegen
Result (graphql folder):
$ ls src/graphql
mutations.js queries.js subscriptions.js enums.js
Client side:
import { orderStatus } from '../../graphql/enums'
Currently the modelgen in amplify has the enum generation for javascript, which is executed by the command amplify codegen models. By default, the output model files(including @model types, enums declaration and schema) will be generated in src/models folder. And by the importing you are all set to use it in your client code.
import { your_enum_name } from 'src/models'
Thanks for this @AaronZyLee, didn't know about it.
From my prospective, it would be still nice to export enums on the client's side, together with mutations, queries, and subs, just for the sake of automation.
Hi @asmajlovicmars, thanks for this feature request. Enums are not native types in Javascript. But, we do generate enum definitions for Flow and Typescript language targets. To take advantage of that, you could update your codegen configuration using amplify codegen update and choose flow for prompt Choose the code generation language target. Hope this helps.
Thank you @phani-srikar. I thought having enums exported into a file would've been convenient. Will check this solution with flow.
Hi @asmajlovicmars. I would like to know a little bit more about your use-case. If we had a schema like:
type Gif @model {
id: ID!
altText: String!
url: String!
category: Category
}
enum Category {
SPORTS
TECH
DOGS
}
and enums.js generated for you which could look like this:
export const category = /* GraphQL */ `
enum Category {
SPORTS
TECH
DOGS
}
`;
export const modelSortDirection = /* GraphQL */ `
enum ModelSortDirection {
ASC
DESC
}
`;
export const modelAttributeTypes = /* GraphQL */ `
enum ModelAttributeTypes {
binary
binarySet
bool
list
map
number
numberSet
string
stringSet
_null
}
`;
How would you use it in mutations, given that you're working on a JS project. Current Developer experience with using enums is to pass them in as Strings to your API calls, like:
import Amplify, { API, graphqlOperation } from '@aws-amplify/api'
import { createGif } from './graphql/mutations'
const gif = {
altText: "my dog gif",
url: "some_url",
category: "DOGS"
}
const newGif = await API.graphql(graphqlOperation(createGif, { input: gif }))
If it were a Typescript(or JS with Flow) project, we generate the enum types like:
export enum Category {
SPORTS = "SPORTS",
TECH = "TECH",
DOGS = "DOGS",
}
which gives you more control over the values enum can accept.
If you could tell me a bit more about how exposing the graphQL enum definitions in a JS project could benefit you, it would be really helpful to form a story around that which could help other developers.
Hi @phani-srikar, my use case is even simpler than this, and it doesn't affect mutations...
It's meant to prevent discrepancies between the front-end, and back-end enum definitions, so following your code, the front-end would collect enums from enums.js, parse the values, and for example populate the dropdown box...
` // something like this: import Amplify, { API, graphqlOperation } from '@aws-amplify/api' import { parse } from 'graphql/language/parser'; import { createGif } from './graphql/mutations' import { category, } from '../../graphql/enums';
const categoryParsed = parse(category).definitions[0].values;
const categories = [];
categoryParsed.map((v) => {
categories.push(v.name.value);
});
// ... populate a dropdown with categories
` This way, when changes are made to the table schema, they will automatically propagate changed values to the front-end. The enums.js file, could be written to a graphql folder, together with queries, mutations, and subscriptions.
Thanks a lot for your quick response @asmajlovicmars. Let me take this to my team and I will let you know any updates soon.
Hi @asmajlovicmars. We had a discussion on this request and a similar one #44 . We will be able to support these use-cases with some of the re-design efforts we are working on. A RFC will soon be released and I would love to hear your comments on it.
@asmajlovicmars - just wanted to let you know that we've publish an RFC to address this and other code generation issues. Would love to have your feedback! aws-amplify/amplify-cli#6898
@renebrandel @phani-srikar
Sorry to revive this zombie thread but I have the exact same use case as @asmajlovicmars.
Reading the RFC I don't understand if the changes have already been implemented and if so, how to acutally get enums generated in js code for my frontend.
I tried changing my codeGenTarget to flow in my .graphqlconfig.yml file but to no avail.
Could you help?
It appears these changes have not been implemented based on comments in the related issues. I'm marking both of these as feature requests.