Joe Hawkins
Joe Hawkins

Reputation: 9971

Convert snake_case to camelCase field names in apollo-server-express

I'm new to GraphQL and Apollo Server, though I have scoured the documentation and Google for an answer. I'm using apollo-server-express to fetch data from a 3rd-party REST API. The REST API uses snake_case for its fields. Is there a simple way or Apollo Server canonical way to convert all resolved field names to camelCase?

I'd like to define my types using camel case like:

type SomeType {
  id: ID!
  createdTime: String
  updatedTime: String
}

but the REST API returns object like:

{
  "id": "1234"
  "created_time": "2018-12-14T17:57:39+00:00",
  "updated_time": "2018-12-14T17:57:39+00:00",
}

I'd really like to avoid manually normalizing field names in my resolvers i.e.

Query: {
    getObjects: () => new Promise((resolve, reject) => {
        apiClient.get('/path/to/resource', (err, response) => {
            if (err) {
                return reject(err)
            }

            resolve(normalizeFields(response.entities))
        })
    })
}

This approach seems error prone, given that I expect the amount of resolvers to be significant. It also feels like normalizing field names shouldn't be a responsibility of the resolver. Is there some feature of Apollo Server that will allow me to wholesale normalize field names or override the default field resolution?

Upvotes: 5

Views: 8284

Answers (3)

Noah Covey
Noah Covey

Reputation: 161

If you are using Knex.js, I highly recommend using an ORM such as Objection.js (https://vincit.github.io/objection.js/). An ORM has lots of very useful features that make querying easier in Node.js, including a function called knexSnakeCaseMappers, which, when passed to the Knex object, will automatically convert snake_case table and column names to camel case before they ever reach your server. Thus your entire server can be written in camel case, matching your GraphQL schema and your client code. Learn more here.

Upvotes: 0

Joe Hawkins
Joe Hawkins

Reputation: 9971

The solution proposed by @Webber is valid.

It is also possible to pass a fieldResolver parameter to the ApolloServer constructor to override the default field resolver provided by the graphql package.

const snakeCase = require('lodash.snakecase')

const snakeCaseFieldResolver = (source, args, contextValue, info) => {
  return source[snakeCase(info.fieldName)]
}

const server = new ApolloServer({ 
  fieldResolver: snakeCaseFieldResolver,
  resolvers,
  typeDefs
})

See the default field resolver in the graphql source code

Upvotes: 8

Webber
Webber

Reputation: 1031

I'd imagine you can place the normalizeFields function inside a graphql middleware right before it returns the results to the client side. Something like so Graphql Middleware.

A middleware would be a good centralized location to put your logic, so you don't need to add the function each time you have a new resolver.

Upvotes: 4

Related Questions