Rambler.iOS #8 - Как не стать жертвой бэкендеров

Post on 22-Jan-2017

324 views 4 download

Transcript of Rambler.iOS #8 - Как не стать жертвой бэкендеров

Как не стать жертвой бекендеров

Ирина Дягилева RAMBLER&Co

Нужна ли валидация ответа сервера?

2

3

Crash-free

4

5

Нужен контракт между клиентом и сервером

и его валидация

6

План

• Валидация ответа сервера

• JSON-схема

• Библиотеки

• Время валидации

• Полезные инструменты

7

LiveJournal@implementation RegistrationResponseValidator

- (NSError *)validateServerResponse:(id)response {

NSError *resultError = nil;

return resultError; }

@end

if (![super validateResponseIsErrorClass:response error:&resultError]) { return resultError; } if(![super validateResponseIsDictionaryClass:response error:&resultError]) { return resultError; }

if (response[@"access_token"] == nil || response[@"displayName"] == nil || response[@"id"] == nil) { resultError = ...; // создание ошибки валидации }

8

Афиша- (NSError *)validateResponseObject:(id)responseObject mapping:(EKManagedObjectMapping *)mapping {

return nil; }

NSError *validationError = [self validateResponseObject:responseObject]; if (validationError) { return [self validationError]; }

NSArray *primaryKeys = mapping.rca_primaryKeys; if (primaryKeys) { for (NSString *primaryKey in primaryKeys) { EKPropertyMapping *propertyMapping = [self propertyMappingForPrimaryKey:primaryKey mapping:mapping]; if (!responseObject[propertyMapping.keyPath]) { return [self validationError]; } } }

9

JSON Schemahttp://json-schema.org/

это JSON

набор инструкций для описания структуры JSON документов

10

Типы объектов JSON JSON Schemastring string

number number/integerobject objectarray arraytrue truefalse falsenull null

11

Примеры json-схем

{ "type": "boolean" }

true

12

false

"true"

30

Строковые типы{ "type": "string", "minLength": 7, "maxLength": 9 }

13

"12345678"

"#FF0000"

"12345"

true

{ "type": "string", "pattern": "^#[0-9a-fA-F]{6}$" }

Строковые типы

14

"#FFFFFf22"

"#3C2FCB"

"FFFFFf22"

"#3C2FCB00"

14

Строковые типы{ "type": "string", "format": "email" }

"email", "date-time", "hostname", "ipv4", "ipv6", "uri"

15

"i.dyagileva@rambler-co.ru" "i.dyagileva"

Числовые типы{ "type": "integer", "minimum": 200, "maximum": 500, "exclusiveMinimum": true, "multipleOf": 5 }

16

205

500

200

104

Перечисления{ "type": "string", "enum": [ "red", "green", "blue" ] }

17

"red"

"blue"

"pink"

"#FFFFFF"

Массивы{ "type": "array", "items": { "type": ["string", "integer"] }, "minItems": 2, "maxItems": 3, "uniqueItems": true }

18

["a", 2]

[4, 5, 6]

[1, 2, 1]

["a", "b", "c", "d"]

Объекты{ "type": "object", "properties": { "articleID": { "type": "string" }, "title": { "type": "string" }, "subtitle": { "type": "string" } },

"required": ["articleID","title"], }

{ "articleID": "1", "title": "Заголовок", "subtitle": "Подзаголовок"

}

{ "articleID": "1", "subtitle": "Подзаголовок"}

19

Объекты{ "type": "object", "properties": { "articleID": { "type": "string" }, "title": { "type": "string" }, "subtitle": { "type": "string" } },

"required": ["articleID","title"], "additionalProperties": false }

{ "articleID": "1", "title": "Заголовок", "subtitle": "Подзаголовок"

}

{ "articleID": "1", "title": "Заголовок", "subtitle": "Подзаголовок", "description": "Описание"

}

20

Определения{ "type": "object", "properties": { "backgroundColor": { "$ref": "#/definitions/color" }, "foregroundColor": { "$ref": "#/definitions/color" } }, "definitions": { "color": { "type": "string", "pattern": "^#[0-9a-fA-F]{6}$" } } }

21

{ "backgroundColor": "#FFFFFF", "foregroundColor": "#FF0000"}

{ "backgroundColor": "FFFFFF", "foregroundColor": "#FF"}

Композиция{ "type": "array", "items": { "allOf": [ { "type": "integer", "minimum": 0

}, { "type": "integer", "multipleOf": 5

} ] } }

22

[5, 15]

[-4, 5]

[0, 0]

[1, 8]

Композиция{ "type": "array", "items": { "anyOf": [ { "type": "integer", "minimum": 0

}, { "type": "integer", "multipleOf": 5

} ] } }

23

[-5, 5]

[-4, 5]

[1, 8]

[1, "8"]

Композиция{ "type": "array", "items": { "oneOf": [ { "type": "integer", "minimum": 0

}, { "type": "integer", "multipleOf": 5

} ] } }

24

[1, 8]

[0, 0]

[1, -5]

[1, -4]

Композиция{ "type": "object", "properties": { "likeValue": { "type": "boolean" }, "place": { "type": "string" }, "event": { "type": "string" } }, "required": ["likeValue"] , "oneOf": [ { "required": ["place"] }, { "required": ["event"] } ] }

25

{ "likeValue": true, "event": "event",}

{ "likeValue": true, "event": "event", "place": "place"}

{ "likeValue": true }

Отрицание{ "type": "array", "items": { "not": { "anyOf": [ { "type": "integer", "minimum": 0 }, { "type": "integer", "multipleOf": 5 } ] } } }

26

[-1, -4]

[-1, -5]

[-8, -8]

[1, -4]

Объявление схемы

{ "$schema": "http://json-schema.org/draft-04/schema#",

}

27

"id": "http://domain.com/schemas/myschema.json"

{

}

"$schema": "http://json-schema.org/draft-04/schema#",

Объявление схемы

28

"id": "http://domain.com/schemas/myschema.json"

Валидатор

29

/** Протокол валидатора ответа сервера */ @protocol ROSResponseValidator <NSObject>

- (BOOL)validateResponse:(id)response withSchema:(NSDictionary *)schema error:(NSError **)error;

@end

30

/** Протокол поставщика json-схем */ @protocol ROSJSONSchemaProvider <NSObject>

- (NSDictionary *)sectionsSchema;

- (NSDictionary *)articleSchema;

@end

31

Библиотеки ObjC

• KiteJSONValidator 39

• JSONTools 41

• JSONSchemaValidation 14

32

Библиотеки Swift

• JSONSchema 96

33

Время валидации

34

3 %12 %

8 %

77 %СкачиваниеВалидацияМаппингПонсомизация

Запрос списка секцийОПЕРАЦИЯ ВРЕМЯ (С)Скачивание 0,2012Валидация 0,0215Маппинг 0,0323Понсомизация 0,0069

Время валидации

35

4 %11 %

30 % 55 %СкачиваниеВалидацияМаппингПонсомизация

Запрос тела статьиОПЕРАЦИЯ ВРЕМЯ (С)Скачивание 0,1040Валидация 0,0560Маппинг 0,0217Понсомизация 0,0071

Полезные ссылки и инструменты

Документация http://json-schema.org/

37

Онлайн-валидатор http://www.jsonschemavalidator.net

38

Онлайн-генератор http://jsonschema.net/

39

Генератор JSON-моков http://json-schema-faker.js.org

40

Итоги

• Предотвращение ошибок и падений приложения

• Документирование структур данных, стандартизация

• Помощь при тестировании

• Генерация моков

41

Контактыivdyagileva@gmail.com

ivdyagileva

https://www.linkedin.com/in/dyagileva

https://github.com/idva