amplify-codegen icon indicating copy to clipboard operation
amplify-codegen copied to clipboard

RFC: Amplify codegen generating enums.js file in src/graphql folder

Open asmajlovicmars opened this issue 5 years ago • 11 comments

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'

asmajlovicmars avatar Nov 03 '20 01:11 asmajlovicmars

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'

AaronZyLee avatar Jan 11 '21 23:01 AaronZyLee

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.

asmajlovicmars avatar Jan 12 '21 00:01 asmajlovicmars

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.

phani-srikar avatar Feb 08 '21 05:02 phani-srikar

Thank you @phani-srikar. I thought having enums exported into a file would've been convenient. Will check this solution with flow.

asmajlovicmars avatar Feb 08 '21 14:02 asmajlovicmars

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.

phani-srikar avatar Feb 16 '21 02:02 phani-srikar

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.

asmajlovicmars avatar Feb 16 '21 16:02 asmajlovicmars

Thanks a lot for your quick response @asmajlovicmars. Let me take this to my team and I will let you know any updates soon.

phani-srikar avatar Feb 16 '21 22:02 phani-srikar

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.

phani-srikar avatar Feb 23 '21 19:02 phani-srikar

@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 avatar Mar 18 '21 14:03 renebrandel

@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?

raphaelfavier avatar Sep 07 '22 12:09 raphaelfavier

It appears these changes have not been implemented based on comments in the related issues. I'm marking both of these as feature requests.

alharris-at avatar Mar 21 '23 17:03 alharris-at