Использование Colander для проверки запросов PATCH

EDIT: мой первоначальный вопрос относился к запросам PUT, я изменил его на PATCH на основе ответа, предоставленного thecoshman.

Я разрабатываю веб-сервис RESTful, используя карниз, и недавно обнаружил дуршлаг. Мой вопрос связан с запросами PATCH. Теперь я знаю, что запросы PUT должны быть полными записями, но не с запросами PATCH. Могу ли я использовать дуршлаг для проверки данных json, прикрепленных к запросу PATCH?

Дуршлаг отлично подходит для проверки запросов POST, поскольку он гарантирует, что у меня есть все правильные данные в моем json, а также удаляет любые посторонние данные.

Вот моя простая схема.

class OrganisationSchemaRecord(MappingSchema):
    orgname = SchemaNode(String())
    fullname = SchemaNode(String())
    description = SchemaNode(String(), missing=drop)

class OrganisationSchema(MappingSchema):
    organisation = OrganisationSchemaRecord()

Это позволяет мне сделать мой код просмотра таким простым.

@view(validators=(unique,), renderer='json', schema=OrganisationSchema)
def collection_post(self):
    """Adds a new organisation"""
    org = DBOrg(**self.request.validated['organisation'])#sqlalchemy model
    DBSession.add(org)
    return {'organisation': org}

Волшебный элемент schema=OrganisationSchema, который проверяет тело json-запроса и размещает его в self.request.validated['organisation'] в соответствии со схемой.

Он также отлично работает с другим моим валидатором, который гарантирует, что первичный ключ еще не используется.

def unique(request):
    if 'organisation' in request.validated: #Implies a validated schema
        orgname = request.validated['organisation']['orgname']
        if DBSession.query(DBOrg).get(orgname):
            request.errors.add('url', 'orgname', 'This organisation already exists!')

Однако, если я хочу обработать запрос PATCH для обновления полей fullname или description, тогда проверка завершится ошибкой, если запрос также не включает значение для orgname, которое я не хочу менять.

Какое лучшее решение? Настаиваю ли я на том, чтобы полные и действительные записи были исправлены на сервере, я определяю другую схему или я что-то упускаю?


person Graeme Stuart    schedule 13.06.2014    source источник


Ответы (1)


честно, пропустил большую часть вопроса, так что, надеюсь, я не пропустил ничего слишком важного.

Should PUT requests be full records - Да, абсолютно.

Запросы PUT помещают всю запись замены в запрошенный вами URI.

Если вы хотите выполнить частичную модификацию, вы должны использовать PATCH (который на удивление менее известен). До PATCH теория была такой: ПОЛУЧИТЬ запись, изменить локально, ВЕРНУТЬ всю запись обратно.

person thecoshman    schedule 13.06.2014
comment
Вы правы, поэтому я думаю, что мне нужно обновить свой вопрос, поскольку я, вероятно, имел в виду запросы PATCH. - person Graeme Stuart; 14.06.2014
comment
Если ваш сервер может (как кажется в настоящее время) поддерживать только полные записи, принимайте их как запросы PUT. Позже вы сможете работать над поддержкой PATCH. - person thecoshman; 14.06.2014
comment
Это то, что я сделал. Мне все еще интересно, как подойти к проверке данных PATCH с помощью дуршлага. - person Graeme Stuart; 16.06.2014
comment
@GraemeStuart Я предполагаю, что вам нужна альтернативная схема, в которой каждый элемент помечен как missing=colander.drop, default=colander.drop, чтобы отсутствующие элементы не отключали этап проверки. Тогда будут проверены только существующие элементы, а отсутствующие элементы будут проигнорированы. Вероятно, вам также необходимо убедиться, что значение unknown в colander.Mapping установлено на 'raise', чтобы значения, не соответствующие элементу схемы, вызывали ошибку. - person Tim Tisdall; 29.07.2015
comment
Спасибо, Тим. Кажется немного странным и не очень СУХИМ иметь две одинаковые схемы для одного и того же ресурса, но я думаю, что это единственный способ. - person Graeme Stuart; 29.07.2015
comment
Я считаю, что наличие двух схем, вероятно, является единственным способом «полного доказательства». Одна схема служит для определения того, что такое полная запись, она должна использоваться при отправке новой записи, при размещении обновленной записи и будет использоваться, когда клиент ПОЛУЧАЕТ запись (хотя эта схема «создания» может иметь необязательные элементы). Наряду с этим у вас будет вторая схема, в которой (почти) все элементы являются необязательными, в основном позволяя клиенту отправлять столько, сколько он хочет, а затем сервер решает, как обновить текущую запись. Вторая схема не могла поддерживать некоторые элементы, что делало их неизменяемыми. - person thecoshman; 30.07.2015
comment
конечно, то, что я там сказал, исходило скорее из чисто теоретического взгляда. Я знаю, что с некоторыми библиотеками JEE у вас может быть гораздо более свободное определение данных, что может упростить сопоставление объекта. У Python может быть подобное, и что с довольно свободными структурами данных, вы можете не рассматривать схему ... хотя, вероятно, это не лучшая из идей. - person thecoshman; 30.07.2015