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

42
Как не стать жертвой бекендеров Ирина Дягилева RAMBLER&Co

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

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

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

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

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

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

2

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

3

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

Crash-free

4

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

5

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

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

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

6

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

План

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

• JSON-схема

• Библиотеки

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

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

7

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

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

Page 9: Rambler.iOS #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

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

JSON Schemahttp://json-schema.org/

это JSON

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

10

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

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

number number/integerobject objectarray arraytrue truefalse falsenull null

11

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

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

{ "type": "boolean" }

true

12

false

"true"

30

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

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

13

"12345678"

"#FF0000"

"12345"

true

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

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

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

14

"#FFFFFf22"

"#3C2FCB"

"FFFFFf22"

"#3C2FCB00"

14

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

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

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

15

"[email protected]" "i.dyagileva"

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

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

16

205

500

200

104

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

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

17

"red"

"blue"

"pink"

"#FFFFFF"

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

Массивы{ "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"]

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

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

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

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

}

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

19

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

Объекты{ "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

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

Определения{ "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"}

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

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

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

} ] } }

22

[5, 15]

[-4, 5]

[0, 0]

[1, 8]

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

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

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

} ] } }

23

[-5, 5]

[-4, 5]

[1, 8]

[1, "8"]

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

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

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

} ] } }

24

[1, 8]

[0, 0]

[1, -5]

[1, -4]

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

Композиция{ "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 }

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

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

26

[-1, -4]

[-1, -5]

[-8, -8]

[1, -4]

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

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

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

}

27

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

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

{

}

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

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

28

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

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

Валидатор

29

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

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

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

@end

30

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

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

- (NSDictionary *)sectionsSchema;

- (NSDictionary *)articleSchema;

@end

31

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

Библиотеки ObjC

• KiteJSONValidator 39

• JSONTools 41

• JSONSchemaValidation 14

32

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

Библиотеки Swift

• JSONSchema 96

33

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

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

34

3 %12 %

8 %

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

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

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

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

35

4 %11 %

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

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

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

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

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

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

37

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

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

38

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

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

39

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

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

40

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

Итоги

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

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

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

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

41

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

Контакты[email protected]

ivdyagileva

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

https://github.com/idva