Make all api fields snake_case (#105)

Change all snake/camelCase mix and match to camelCase everywhere

Fix conversion to not interfer with service interceptors

Add dynamic conversion between camelCase and snake_case to services

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/105
This commit is contained in:
konrad 2020-04-12 21:54:46 +00:00
parent de36296bac
commit 4a413e7f3c
60 changed files with 296 additions and 189 deletions

View file

@ -1,5 +1,7 @@
import axios from 'axios'
import {reduce, replace} from 'lodash'
import {camelCase} from 'camel-case'
import {snakeCase} from 'snake-case'
let config = require('../../public/config.json')
@ -40,19 +42,25 @@ export default class AbstractService {
// Set the interceptors to process every request
let self = this
this.http.interceptors.request.use( (config) => {
this.http.interceptors.request.use((config) => {
switch (config.method) {
case 'post':
if(this.useUpdateInterceptor())
config.data = JSON.stringify(self.beforeUpdate(config.data))
if (this.useUpdateInterceptor()) {
config.data = self.beforeUpdate(config.data)
}
config.data = JSON.stringify(this.modelToSnakeCase(config.data))
break
case 'put':
if(this.useCreateInterceptor())
config.data = JSON.stringify(self.beforeCreate(config.data))
if (this.useCreateInterceptor()) {
config.data = self.beforeCreate(config.data)
}
config.data = JSON.stringify(this.modelToSnakeCase(config.data))
break
case 'delete':
if(this.useDeleteInterceptor())
config.data = JSON.stringify(self.beforeDelete(config.data))
if (this.useDeleteInterceptor()) {
config.data = self.beforeDelete(config.data)
}
config.data = JSON.stringify(this.modelToSnakeCase(config.data))
break
}
return config
@ -66,7 +74,7 @@ export default class AbstractService {
) {
this.http.defaults.headers.common['Authorization'] = 'Bearer ' + localStorage.getItem('token')
}
this.paths = {
create: paths.create !== undefined ? paths.create : '',
get: paths.get !== undefined ? paths.get : '',
@ -112,7 +120,7 @@ export default class AbstractService {
errorHandler(error) {
return Promise.reject(error)
}
/////////////////
// Helper functions
///////////////
@ -231,6 +239,32 @@ export default class AbstractService {
// Preprocessors
////////////
/**
* Transforms field names to camel case.
* @param model
* @returns {*}
*/
modelToCamelCase(model) {
let parsedModel = {}
for (const m in model) {
parsedModel[camelCase(m)] = model[m]
}
return parsedModel
}
/**
* Transforms field names to snake case - used before making an api request.
* @param model
* @returns {*}
*/
modelToSnakeCase(model) {
let parsedModel = {}
for (const m in model) {
parsedModel[snakeCase(m)] = model[m]
}
return parsedModel
}
/**
* Default preprocessor for get requests
* @param model
@ -295,12 +329,16 @@ export default class AbstractService {
*/
getM(url, model = {}, params = {}) {
const cancel = this.setLoading()
model = this.beforeGet(model)
return this.http.get(this.getReplacedRoute(url, model), {params: params})
const finalUrl = this.getReplacedRoute(url, model)
return this.http.get(finalUrl, {params: params})
.catch(error => {
return this.errorHandler(error)
})
.then(response => {
response.data = this.modelToCamelCase(response.data)
return Promise.resolve(this.modelGetFactory(response.data))
})
.finally(() => {
@ -325,7 +363,9 @@ export default class AbstractService {
const cancel = this.setLoading()
model = this.beforeGet(model)
return this.http.get(this.getReplacedRoute(this.paths.getAll, model), {params: params})
const finalUrl = this.getReplacedRoute(this.paths.getAll, model)
return this.http.get(finalUrl, {params: params})
.catch(error => {
return this.errorHandler(error)
})
@ -338,16 +378,17 @@ export default class AbstractService {
return this.modelGetAllFactory(entry)
}))
}
if(response.data === null) {
if (response.data === null) {
return Promise.resolve([])
}
response.data = this.modelToCamelCase(response.data)
return Promise.resolve(this.modelGetAllFactory(response.data))
})
.finally(() => {
cancel()
})
}
/**
* Performs a put request to the url specified before
* @param model
@ -359,18 +400,21 @@ export default class AbstractService {
}
const cancel = this.setLoading()
return this.http.put(this.getReplacedRoute(this.paths.create, model), model)
const finalUrl = this.getReplacedRoute(this.paths.create, model)
return this.http.put(finalUrl, model)
.catch(error => {
return this.errorHandler(error)
})
.then(response => {
response.data = this.modelToCamelCase(response.data)
return Promise.resolve(this.modelCreateFactory(response.data))
})
.finally(() => {
cancel()
})
}
/**
* Performs a post request to the update url
* @param model
@ -382,11 +426,14 @@ export default class AbstractService {
}
const cancel = this.setLoading()
return this.http.post(this.getReplacedRoute(this.paths.update, model), model)
const finalUrl = this.getReplacedRoute(this.paths.update, model)
return this.http.post(finalUrl, model)
.catch(error => {
return this.errorHandler(error)
})
.then(response => {
response.data = this.modelToCamelCase(response.data)
return Promise.resolve(this.modelUpdateFactory(response.data))
})
.finally(() => {
@ -405,11 +452,14 @@ export default class AbstractService {
}
const cancel = this.setLoading()
return this.http.delete(this.getReplacedRoute(this.paths.delete, model), model)
const finalUrl = this.getReplacedRoute(this.paths.delete, model)
return this.http.delete(finalUrl, model)
.catch(error => {
return this.errorHandler(error)
})
.then(response => {
response.data = this.modelToCamelCase(response.data)
return Promise.resolve(response.data)
})
.finally(() => {