Глагол REST для изменения состояния - можем ли мы договориться о POST?
blockquote>Эталонной реализацией REST является Всемирная паутина, которая была катастрофически успешной, хотя HTML (доминирующее медиа type) указана только поддержка
GET
иPOST
.Использование
POST
для небезопасных операций прекрасно .Хотя start выглядит как глагол (нарушающий REST-практики)
blockquote>Нет - REST не заботится о написании URI. В этом и заключается суть: сервер может в любой момент изменить URI в ссылках, так как клиенты просто переходят по ссылкам.
Тем не менее, есть проблема с предложенными вами идентификаторами, которую вы можете рассмотреть
/coffeemachines/{id} /coffeemachines/{id}/start
Что касается REST, то это различных ресурсов. Это означает, что ваша локально кэшированная копия
/coffeemachines/{id}
не является недействительной , когда выPOST
запросите к/coffeemachines/{id}/start
.Если вы хотите воспользоваться преимуществами поддержки кэширования, которая уже встроена в независимые от домена компоненты, то вы хотите, чтобы цель
POST
соответствовала целиGET
:/coffeemachines/{id}
[ 1135]
/coffeemachines/{id}/start
, в этом дизайне, не является цельюPOST
, но вместо этого является идентификатором ресурса формы, который отправляет стартовые сообщения в/coffeemachines/{id}
. Аналогично,/coffeemachines/{id}/stop
идентифицирует ресурс формы, который отправляет сообщения остановки.Представление кофемашины будет включать ссылки на эти формы, когда переходы разрешены; например, когда кофемашина выключена, то представление кофемашины, возвращенное
GET
, будет включать ссылку на стартовую форму, но не ссылку на форму остановки.
/coffeemachines/{id}/start
и/coffeemachines/{id}/stop
отличаются от ресурсов/coffeemachines/{id}
и поэтому могут иметь свои собственные политики кэширования.Конечно, не требуется , чтобы формы были отдельными ресурсами - механизм также работал бы, если бы формы были частью представления самого ресурса
/coffeemachines/{id}
.Могу ли я попросить вас рассказать о POST против PATCH
blockquote>Я обнаружил, что это наблюдение Роя Филдинга мне помогло:
[ 1142] HTTP не пытается требовать, чтобы результаты GET были безопасными. Для этого требуется, чтобы семантика операции была безопасной, и, следовательно, это ошибка реализации, а не интерфейса или пользователя этого интерфейса, если в результате произойдет что-либо, что приведет к потере свойстваblockquote>
PATCH имеет более строгую семантику, чем POST ; это означает, что клиенты (и общие компоненты) могут сделать более сильными предположения о том, что происходит.
Так в следующих примерах:
PATCH /foo HTTP/1.1 Content-Type: application/json-patch+json POST /foo HTTP/1.1 Content-Type: application/json-patch+json
Сервер может обрабатывать эти сообщения точно таким же образом. Клиенты, которые распознают метод PATCH, распознают, что небезопасные изменения на сервере должны быть «все или ничего» («Сервер ДОЛЖЕН применять весь набор изменений атомарно ...») и могут использовать это по своему усмотрению, но с POST это дополнительное ограничение отсутствует и не может быть принято.
Спецификация PATCH отмечает:
Сравнение с POST еще сложнее, потому что POST используется в самых разных ситуациях и может охватывать операции PUT и PATCH, если сервер выбирает. Если операция не изменяет ресурс, идентифицируемый Request-URI предсказуемым образом, следует рассмотреть POST вместо PATCH или PUT.
BLOCKQUOTE>
Я просто боролся с подобной проблемой, но не хотел накладных расходов на функцию. Я пришел к следующему запросу:
SELECT myfield::integer FROM mytable WHERE myfield ~ E'^\\d+$';
Postgres сокращает свои условные выражения, так что вы не должны получать нецелые числа, попадающие в ваш :: integer cast. Он также обрабатывает значения NULL (они не будут соответствовать регулярному выражению).
Если вы хотите, чтобы вместо выбора использовались нули, тогда оператор CASE должен работать:
SELECT CASE WHEN myfield~E'^\\d+$' THEN myfield::integer ELSE 0 END FROM mytable;
Следующая функция делает
error_result
) для не, castable результаты, например, abc
или 999999999999999999999999999999999999999999
null
, поскольку null
bigints
, сравнены с lower_bound
к, например, осуществляют положительные значения только [1 111] CREATE OR REPLACE FUNCTION cast_to_bigint(text)
RETURNS BIGINT AS $
DECLARE big_int_value BIGINT DEFAULT NULL;
DECLARE error_result BIGINT DEFAULT -1;
DECLARE lower_bound BIGINT DEFAULT 0;
BEGIN
BEGIN
big_int_value := CASE WHEN $1 IS NOT NULL THEN GREATEST(TRIM($1)::BIGINT, lower_bound) END;
EXCEPTION WHEN OTHERS THEN
big_int_value := error_result;
END;
RETURN big_int_value;
END;
Если данные должны быть целыми числами, и вам нужны только эти значения как целые числа, почему бы вам не пройти всю милю и преобразовать столбец в целочисленную столбец?
затем Вы можете сделать это преобразование нелегальных ценностей в нули только один раз, в точке системы, в которой данные вставляются в таблицу.
При вышеуказанном преобразовании вы заставляете Postgres снова преобразовать эти значения снова и снова для каждой единицы в каждом запросе для этой таблицы - это может серьезно ухудшить производительность, если вы делаете много запросов против этого столбца в этой таблице.
Вы также можете создать свою собственную функцию преобразования, внутри, в которой вы могут использовать блоки исключения:
CREATE OR REPLACE FUNCTION convert_to_integer(v_input text)
RETURNS INTEGER AS $$
DECLARE v_int_value INTEGER DEFAULT NULL;
BEGIN
BEGIN
v_int_value := v_input::INTEGER;
EXCEPTION WHEN OTHERS THEN
RAISE NOTICE 'Invalid integer value: "%". Returning NULL.', v_input;
RETURN NULL;
END;
RETURN v_int_value;
END;
$$ LANGUAGE plpgsql;
тестирование:
=# select convert_to_integer('1234');
convert_to_integer
--------------------
1234
(1 row)
=# select convert_to_integer('');
NOTICE: Invalid integer value: "". Returning NULL.
convert_to_integer
--------------------
(1 row)
=# select convert_to_integer('chicken');
NOTICE: Invalid integer value: "chicken". Returning NULL.
convert_to_integer
--------------------
(1 row)
SELECT CASE WHEN myfield="". THEN 0 ELSE myfield::integer END FROM mytable
Я никогда не работал с PostgreSQL, но я проверил manual на правильность синтаксиса выражений IF в SELECT запросах.