При передаче объекта через API, например, в формате JSON без схемы, каков идеальный способ вернуть несуществующее строковое свойство? Я знаю, что есть разные способы сделать это, как в примерах в приведенных ниже ссылках.
Я уверен, что я использовал нуль в прошлом, но у меня нет веских причин для этого. Кажется, просто использовать null при работе с базой данных. Но база данных выглядит как деталь реализации, которая не должна касаться стороны на другой стороне API. Например, они, вероятно, используют хранилище данных без схемы, в котором хранятся только свойства со значениями (не нулевыми).
С точки зрения кода, ограничение строковых функций для работы только с одним типом, т. Е. string
(Не нулевым), облегчает их доказательство; избегание нуля также является причиной наличия Option
объекта. Итак, если код, который генерирует запрос / ответ, не использует нуль, я думаю, что код на другой стороне API не будет вынужден использовать ноль тоже.
Мне скорее нравится идея использовать пустую строку как простой способ избежать использования нуля. Один аргумент, который я слышал об использовании null и против пустой строки, состоит в том, что пустая строка означает, что свойство существует. Хотя я понимаю разницу, мне также интересно, является ли это просто деталями реализации, и если использование пустой или пустой строки имеет какое-либо реальное значение для жизни. Мне также интересно, если пустая строка аналогична пустому массиву.
Итак, что является лучшим способом сделать это, чтобы решить эти проблемы? Зависит ли это от формата передаваемого объекта (схема / без схемы)?
источник
if( value === null) { use parent value; }
Однако, если вы установите дочернее значение, даже в пустую строку (например, переопределите родительское значение по умолчанию пустым), то как вы «наследуете» значение? Для меня установка его в ноль будет означать «сбросить это значение, чтобы мы знали, использовать родительское значение».null
(это правда, чтоnull
избегается как таковой), спрашивающий означает «Вернуть ненулевое значение» [Объект] (то есть: пустая строка, пустой массив и т. Д.), Когда они напиши "избегай".Ответы:
TLDR; Удалить нулевые свойства
Первое, что нужно иметь в виду, это то, что приложения на их краях не являются объектно-ориентированными (и не функциональными, если программирование в этой парадигме). JSON, который вы получаете, не является объектом и не должен рассматриваться как таковой. Это просто структурированные данные, которые могут (или не могут) преобразовываться в объект. В общем случае ни одному входящему JSON не следует доверять как бизнес-объекту, пока он не будет проверен как таковой. Тот факт, что он десериализован, не делает его действительным. Поскольку JSON также имеет ограниченные примитивы по сравнению с внутренними языками, часто стоит создать DTO - JML -выравнивание для входящих данных. Затем используйте DTO для создания бизнес-объекта (или попытки ошибки) для выполнения операции API.
Когда вы рассматриваете JSON как просто формат передачи, имеет больше смысла пропускать свойства, которые не установлены. Это меньше, чтобы отправить через провод. Если ваш внутренний язык по умолчанию не использует пустые значения, вы, вероятно, можете настроить десериализатор на выдачу ошибки. Например, моя общая установка для Newtonsoft.Json переводит нулевые / отсутствующие свойства только в / из
option
типов F # и в противном случае выдаст ошибку. Это дает естественное представление о том, какие поля являются необязательными (сoption
типом).Как всегда, обобщения только дошли до вас. Вероятно, есть случаи, когда свойство по умолчанию или нулевое свойство подходит лучше. Но ключ не в том, чтобы рассматривать структуры данных на границе вашей системы как бизнес-объекты. Бизнес-объекты должны иметь деловые гарантии (например, имя не менее 3 символов) при успешном создании. Но структуры данных, снятые с провода, не имеют реальных гарантий.
источник
Обновление: я немного отредактировал ответ, потому что это могло привести к путанице.
Переход с пустой строкой является окончательным нет. Пустая строка все еще является значением, она просто пустая. Значение не должно быть указано , используя конструкцию , которая не представляет ничего
null
.С точки зрения разработчика API, существует только два типа свойств:
null
.Это ясно дает понять, что когда свойство является обязательным, т.е. требуется, это никогда не может быть
null
.С другой стороны, если необязательное свойство объекта не будет установлено и оставлено пустым, я предпочитаю в любом случае оставить их в ответе со
null
значением. Исходя из моего опыта, клиентам API легче реализовать синтаксический анализ, поскольку им не требуется проверять, существует ли свойство на самом деле или нет, потому что оно всегда есть, и они могут просто преобразовать ответ в свой пользовательский DTO, обрабатываяnull
значения по желанию.Динамическое включение / удаление полей из сил реагирования, включая дополнительные условия для клиентов.
В любом случае, какой бы путь вы ни выбрали, убедитесь, что вы поддерживаете его согласованным и хорошо документированным. Таким образом, действительно не имеет значения, что вы используете для своего API, если его поведение предсказуемо.
источник
null
для ссылок. Смешивание значений со ссылками - одна из моих задач. Как вы отличаете необязательные поля сnull
не необязательными строковыми полями, которые имеютnull
значение? Повторный анализ, разве не проверка существования свойств делает синтаксический анализатор более хрупким?null
чтобы указать значение является необязательным. Таким образом, когда вы определяете объект, который имеет необязательное строковое свойство, а потребитель не имеет этого свойства, он должен отправить пустую строку для этого свойства. Это правильно?null
Использование зависит от приложения / языкаВ конечном счете, выбор того, использовать ли его
null
в качестве допустимого значения приложения или нет, во многом определяется вашим приложением и языком программирования / интерфейсом / гранью.На фундаментальном уровне я бы рекомендовал использовать разные типы, если есть разные классы значений.
null
может быть вариант, если ваш интерфейс позволяет это, и есть только два класса свойства, которое вы пытаетесь представить. Пропуск свойства может быть вариантом, если ваш интерфейс или формат позволяет это. Новый агрегатный тип (класс, объект, тип сообщения) может быть другой опцией.Для вашего примера строки, если это на языке программирования, я бы задал себе пару вопросов.
Option
, вероятно, будет лучше для вашего дизайна интерфейса.Option
вероятно, лучше всего подходит для этого случая, если ваша строка не имеет значения NULL. Тем не менее, вам, вероятно, всеnull
равно придется проверять пользовательский ввод на наличие строкового значения, поэтому я бы, вероятно, отложил вопрос до первой строки: сколько типов значений я хочу / буду представлять.null
ошибка программиста в моем языке программирования? К сожалению,null
часто это значение по умолчанию для неинициализированных (или неявно инициализированных) указателей или ссылок в некоторых языках. Является лиnull
значение приемлемым в качестве значения по умолчанию? Это безопасно в качестве значения по умолчанию? Иногдаnull
указывает на освобожденные значения. Должен ли я предоставить потребителям моего интерфейса указание этих потенциальных проблем с управлением памятью или инициализацией в их программе? Что такое режим отказа такого звонка перед лицом таких проблем? Находится ли вызывающий абонент в том же процессе или потоке, что и мой, чтобы такие ошибки представляли высокий риск для моего приложения?В зависимости от ваших ответов на эти вопросы, вы, вероятно, сможете определить, подходит ли
null
вам ваш интерфейс.Пример 1
null
это возможное строковое значение, возвращаемое после неудачной попытки выделить место для строки.Ответ:
null
вероятно, не подходитОбоснование:
null
в этом случае фактически используется для указания двух разных типов значений. Первое может быть значением по умолчанию, которое пользователь вашего интерфейса может захотеть установить. К сожалению, второе значение - это флаг, указывающий, что ваша система работает неправильно. В таких случаях вы, вероятно, захотите потерпеть неудачу настолько безопасно, насколько это возможно (что бы это ни значило для вашей системы).Пример 2
char *
член.NULL
char *
члена для вашего API может быть указано одним значением:NULL
char *
элемент.Ответ:
NULL
может быть уместнымОбоснование: существует небольшая вероятность того, что ваша структура пройдет
NULL
проверку, но не будет инициализирована. Однако ваш API может быть не в состоянии учесть это, если у вас нет какой-либо контрольной суммы для значения структуры и / или проверки диапазона адреса структуры. Линтеры MISRA-C могут помочь пользователям вашего API, помечая использование структур перед их инициализацией. Однако, что касаетсяchar *
члена, если указатель на структуру указывает на инициализированную структуру,NULL
это значение по умолчанию для неопределенного члена в инициализаторе структуры. Следовательно,NULL
может служить безопасным значением по умолчанию дляchar *
члена структуры в вашем приложении.Если бы он был в интерфейсе сериализации, я бы задал себе следующие вопросы о том, использовать ли null в строке.
null
показатель потенциальной клиентской стороны ошибки? Для JSON в JavaScript это, вероятно, нет, посколькуnull
не обязательно используется как указание на ошибку выделения. В JavaScript это используется как явное указание на отсутствие объекта в ссылке, которая будет установлена проблематично. Однако существуют не-javascript-парсеры и сериализаторы, которые отображают JSONnull
на нативныйnull
тип. Если это так, то возникает вопрос о том,null
нормально ли использование родного языка для вашей конкретной комбинации языка, анализатора и сериализатора.null
фактически указывает, что у вас полностью новый тип сообщения. Для ваших потребителей формата сериализации может быть проще указать совершенно другой тип сообщения. Это гарантирует, что их проверка и логика приложения могут иметь четкое разделение между двумя различиями сообщений, которые предоставляет ваш веб-интерфейс.Генеральный Совет
null
не может быть значением ребра или интерфейса, который его не поддерживает. Если вы используете что-то очень необычное в наборе значений свойств (например, JSON), попробуйте использовать какую-либо форму схемы или проверку в программном обеспечении конечного пользователя (например, JSON Schema ), если можете. Если это API языка программирования, проверяйте пользовательский ввод статически (если это возможно) (с помощью набора текста) или настолько громко, насколько это целесообразно во время выполнения (так называемое защитное программирование на интерфейсах, обращенных к потребителю). Что важно, документируйте или определите край, так что нет никаких сомнений относительно:источник
Вот мой личный анализ этих вопросов. Он не подкреплен какой-либо книгой, бумагой, учебой или чем-то еще, только моим личным опытом.
Пустые строки как
null
Для меня это не пойдет. Не смешивайте семантику пустой строки с семантикой неопределенной. Во многих случаях они могут быть взаимозаменяемыми, но вы можете столкнуться со случаями, когда неопределенное и определенное, но пустое означают что-то другое.
Какой-то глупый пример: скажем, есть атрибут, который хранит внешний ключ, и этот атрибут не определен или есть
null
, это будет означать, что отношение не определено, тогда как пустую строку""
можно понимать как определенное отношение и Идентификатор внешней записи - это пустая строка.Не определено против
null
Это не черная или белая тема. У обоих подходов есть свои плюсы и минусы.
В пользу явного определения
null
ценностей существуют следующие плюсы:В пользу предположения, что несуществующий ключ равен семантике
null
:Если API-интерфейс каким-то образом стабилен, и вы тщательно его документируете, я думаю, что можно утверждать, что несуществующий ключ соответствует значению
null
. Но если это более хаотично и хаотично (как это часто бывает), я думаю, вы можете избежать головной боли, если явно определите каждое значение в каждом сообщении. Т.е. если сомневаюсь, я склонен следовать многословному подходу.Все сказанное, самое главное: четко изложите свои намерения и будьте последовательны. Не делай одно здесь, а другое там. Предсказуемое программное обеспечение - лучшее программное обеспечение.
источник
null
. Другой пример: в игре есть объект персонажа, и он имеет атрибут «партнер».null
Партнер явно означает , что нет партнера на всех, но""
может быть понято как есть партнер , чье имя""
.null
пустую строку. Может быть, рендеринг в форме, но никогда в модели данных.name
о котором я говорил, вы позволите назвать имя партнера пустым?Я бы поставил пустую строку в ситуации, когда строка присутствует, и она оказалась пустой строкой. Я бы поставил ноль в ситуации, когда я хочу явно сказать «нет, этих данных нет». И опустите ключ, чтобы сказать: «Нет данных, не беспокойтесь».
Вы судите, какая из этих ситуаций может произойти. Имеет ли смысл в вашем приложении иметь пустые строки? Вы хотите провести различие между тем, чтобы сказать явно «нет данных», используя ноль, и неявно, не имея значения? У вас должны быть обе возможности (ноль и отсутствие ключа), если клиент должен различить обе эти возможности.
Теперь имейте в виду, что это все о передаче данных. То, что получатель делает с данными, является их бизнесом, и они будут делать то, что им наиболее удобно. Получатель должен иметь возможность обрабатывать все, что вы на него бросаете (возможно, отклоняя данные) без сбоев.
Если нет других соображений, я бы передал то, что наиболее удобно для отправителя, и задокументировал это. Я бы предпочел вообще не отправлять отсутствующие значения, потому что это, вероятно, улучшит скорость кодирования, передачи и анализа JSON.
источник
Хотя я не могу сказать, что лучше, это почти наверняка не простая деталь реализации , она меняет структуру того, как вы можете взаимодействовать с этой переменной.
Если что-то может быть нулевым, вы всегда должны обращаться с ним, как если бы оно было нулевым в какой-то момент , поэтому у вас всегда будет два рабочих процесса , один для нулевого, другой для допустимой строки. Разделение рабочего процесса не обязательно является плохой вещью, поскольку вы можете использовать немало обработчиков ошибок и особых случаев, но это запутывает ваш код.
Если вы всегда будете взаимодействовать со строкой одним и тем же способом, вам, вероятно, будет легче оставаться в голове .
Так же, как и с любым вопросом «что лучше», у меня остается ответ: это зависит . Если вы хотите разделить ваш рабочий процесс и более четко захватить, когда что-то не установлено, используйте null. Если вы предпочитаете, чтобы программа просто продолжала в том же духе, используйте пустую строку. Важно то, что вы последовательны , выберите общий возврат и придерживайтесь этого.
Учитывая то, что вы создаете API, я бы порекомендовал придерживаться пустой строки , так как пользователь меньше компенсирует это, потому что, как пользователь API, я не буду знать каждую причину, по которой ваш API может дать мне нулевое значение, если вы не ' очень хорошо задокументированы, что некоторые пользователи не будут читать в любом случае.
источник
string
s, а не null. Если API использует нуль, то в какой-то момент производитель должен создать этоnull
для соответствия API. Тогда потребителюnull
тоже нужно справиться . Но я думаю, что я понял, что вы говорите, просто решите и определите API с правами, верно? Означает ли это, что нет ничего плохого в любом из них?Документ!
TL; DR>
Делайте так, как считаете нужным - иногда контекст, в котором он используется, имеет значение. Пример, привязка переменных к Oracle SQL: пустая строка интерпретируется как NULL.
Просто я бы сказал - убедитесь, что вы задокументировали каждый упомянутый сценарий
Ваш код может действовать по-разному - запишите, как ваш код реагирует на него:
Кроме того, вы должны вести себя последовательно и, возможно, перенимать некоторые из своих лучших практик. Документируйте это последовательное поведение. Примеры:
источник
tl; dr - если вы используете это: будьте последовательны в том, что это значит.
Если бы вы включили
null
, что бы это значило? Существует множество вещей, что бы это могло значить. Одного значения просто недостаточно для представления отсутствующего или неизвестного значения (и это только две из множества возможностей: например, отсутствует - оно было измерено, но мы еще не знаем его. Неизвестно - мы не пытались измерить Это.)В примере, с которым я недавно сталкивался, поле могло быть пустым, потому что об этом не сообщалось для защиты чьей-либо конфиденциальности, но оно было известно на стороне отправителя, неизвестно на стороне отправителя, но известно исходному репортеру или неизвестно обоим. И все это имело значение для получателя. Поэтому обычно одного значения недостаточно.
С предположением открытого мира (вы просто не знаете о вещах, которые не заявлены), вы просто оставили бы это, и это могло быть что угодно. С предположением о замкнутом мире (вещи, которые не указаны, являются ложными, например, в SQL), вы лучше проясните, что
null
означает, и будьте настолько последовательны с этим определением, насколько сможете ...источник