TL/DR: Какой хороший способ использовать подписанное соглашение об именах (RoR) с помощью соглашения о назначении имен для camelCased clientide (JS)
Серверные среды программирования, такие как Ruby on Rails, используют переопределенные переменные. Обычно JavaScript использует переменные camelCased. Это проблематично при отправке данных с клиента на сервер.
Например, рассмотрите отправку пользовательской информации клиенту. В базе данных может быть свойство num_times_ordered, но в JavaScript вы обычно хотели бы ссылаться на это как numTimesOrdered.
Кто-нибудь придумал элегантный способ справиться с этим? Вот некоторые варианты, ни один особенно приятный:
Я склоняюсь к № 3 и использую символы подчеркивания в своем JavaScript. Это будет выглядеть странно, если я буду использовать сторонние библиотеки camelCased.
Я считаю, что ember.js(через Ember Data) принимает подход №1: преобразование подчеркнутого JSON в camelCase на стороне клиента при извлечении; и делать обратный, прежде чем отправлять обратно на сервер.
Я работал над небольшой библиотекой, которая выполняет эти преобразования: https://github.com/domchristie/humps, что позволяет делать такие вещи, как:
// GET
$.ajax({
url: '/posts',
dataType: 'json',
success: function(data, status, xhr) {
data = humps.camelizeKeys(data);
}
});
// POST
$.ajax({
type: 'POST',
url: '/posts'
dataType: 'json',
data: humps.decamelizeKeys({
title: "Foo",
publishedAt: "2012-09-03T21:35:46.068Z"
})
});
// Sends: { title: "Foo", published_at: "2012-09-03T21:35:46.068Z" }
Я должен добавить, что он не был сильно протестирован, но приветствуются вклады!
Воскрешая это для более современного подхода.
Это отличный прецедент для перехватчиков axios
В принципе, определите класс клиента и добавьте перед/после перехватчика, который преобразует данные запроса/ответа.
export default class Client {
get(url, data, successCB, catchCB) {
return this._perform('get', url, data, successCB, catchCB);
}
post(url, data, successCB, catchCB) {
return this._perform('post', url, data, successCB, catchCB);
}
_perform(method, url, data, successCB, catchCB) {
// https://github.com/axios/axios#interceptors
// Add a response interceptor
axios.interceptors.response.use((response) => {
response.data = toCamelCase(response.data);
return response;
}, (error) => {
error.data = toCamelCase(error.data);
return Promise.reject(error);
});
// Add a request interceptor
axios.interceptors.request.use((config) => {
config.data = toSnakeCase(config.data);
return config;
}, (error) => {
return Promise.reject(error);
});
return axios({
method: method,
url: API_URL + url,
data: data,
headers: {
'Content-Type': 'application/json',
},
}).then(successCB).catch(catchCB)
}
}
Здесь gist с более длинным примером, использующим React/axios.