Мой знакомый устраивается в крупный российский маркетплейс, после прохождения сотрудника отдела персонала, его попросили сделать тестовое задание с условием уложится в 2 часа.

Разберем задание и попробуем его решить.

Постановка задачи

Разработать и прислать рабочее расширение с HTTP-сервисом для постраничного получения номенклатуры. Ответить на вопросы по решению.

Требования уровень 1:

  • Параметры запроса: номер страницы, количество элементов на странице.
  • Формат возвращаемых данных: JSON.
  • Состав данных: ГУИД, Наименование, Единица измерения (наименование).

Требования уровень 2:

  • Авторизация в сервисе производится по JWT-токену (валидация токена не требуется, может быть произвольным).
  • Реализовать возвращаемые коды ошибок:
    • 401 – ошибка авторизации (токен не указан);
    • 404 – отсутствует страница.

Требования уровень 3: Подготовить и прислать спецификацию в формате OpenAPI.

Пример: Запрос: http://localhost/demo/hs/nom/v1?p=4&c=10

Ответ:

[
   {
      "uid":"51f45cb4-1359-44as-9a6d-f058142eefa6",
      "name":"Стол",
      "unit":"шт"
   },
   {
      "uid":"e399d117-44cb-4c52-966d-0c8c6b93bf3f",
      "name":"Стул",
      "unit":"шт"
   }
]

Решение

Если захотим тестировать http-сервис не забываем настроить веб-сервер.

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

Решаем требование 1

Создаем HTTP-сервис «ПолучитьНоменклатуру» с корневым url «nom»

Создание HTTP-сервиса в 1с HTTP-сервис 1с который возвращает номенклатуру

добавляем шаблон url и метод get

Создание методов http-сервиса 1с http-сервис 1с шаблон url Создание обработчика методов http-сервиса 1с Метод get

Пишем код

Функция v1_МетодGet(Запрос)
	// Создаем запрос который вернет нам список номенклатуры по параметрам
	тЗапрос = Новый Запрос("ВЫБРАТЬ
	|	Номенклатура.Наименование КАК name,
	|	Номенклатура.ЕдиницаИзмерения КАК unit,
	|	Номенклатура.Ссылка КАК Ссылка,
	|	АВТОНОМЕРЗАПИСИ() КАК НомерЗаписи
	|ПОМЕСТИТЬ ВТ_ВсяНоменклатураСНомерами
	|ИЗ
	|	Справочник.Номенклатура КАК Номенклатура
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ ПЕРВЫЕ _&КоличествоНаСтранице_
	|	ВТ_ВсяНоменклатураСНомерами.name КАК name,
	|	ВТ_ВсяНоменклатураСНомерами.unit КАК unit,
	|	ВТ_ВсяНоменклатураСНомерами.Ссылка КАК Ссылка
	|ИЗ
	|	ВТ_ВсяНоменклатураСНомерами КАК ВТ_ВсяНоменклатураСНомерами
	|	ВТ_ВсяНоменклатураСНомерами.НомерЗаписи >= &Страница
	|
	|УПОРЯДОЧИТЬ ПО
	|	ВТ_ВсяНоменклатураСНомерами.НомерЗаписи");
	
    Запрос.Текст = СтрЗаменить(Запрос.Текст,"_&КоличествоНаСтранице_",Запрос.ПараметрыЗапроса["c"]);                       
	Запрос.УстановитьПараметр("Страница",Запрос.ПараметрыЗапроса["p"] * Запрос.ПараметрыЗапроса["c"]);	// номер страницы 
                           
	РезультатЗапроса = тЗапрос.Выполнить();
	
	МассивВозврата = Новый Массив;
	
	Если РезультатЗапроса.Пустой() Тогда
		// В ТЗ ничего нет про случай когда по параметрам ничего не нашлось
		// в этом случае вернем пустой массив
	Иначе
		Выборка = РезультатЗапроса.Выбрать();
		
		Пока Выборка.Следующий() Цикл
			// Собираем данные для возврата
			СтрокаСтруктура	= Новый Структура("uid,name,unit");
			ЗаполнитьЗначенияСвойств(СтрокаСтруктура,Выборка);
			СтрокаСтруктура.uid = XMLСтрока(Выборка.Ссылка);	
			МассивВозврата.Добавить(СтрокаСтруктура);	
		КонецЦикла;
	КонецЕсли;	
	
	// Переводим нужные данные в формат JSON
	ЗаписьJSON = Новый ЗаписьJSON;
	ЗаписьJSON.УстановитьСтроку();  
	ЗаписатьJSON(ЗаписьJSON, МассивВозврата);            
	JSONСтрока = ЗаписьJSON.Закрыть();
	
	// Формируем ответ
	Ответ = Новый HTTPСервисОтвет(200);
	Ответ.Заголовки.Вставить("Content-Type", "text/html; charset=utf-8");
	Ответ.УстановитьТелоИзСтроки(JSONСтрока);
	
	Возврат Ответ;
КонецФункции

Проверяем себя и выполняем запрос.

Результат работы HTTP-сервиса 1с Результат запроса к http-сервису получения номенклатуры

Отлично, требование 1 выполнено, потрачено около 15 минут.

Переходим ко второй части, реализация авторизации по JWT-токену, если нам повезло и уже настало 8.3.21, то просто используем новый функционал 1с.

А я реализую сам, без валидации, будет только проверка на пустой токен, а также сразу добавлю обработку двух ошибок и сделаю небольшой рефакторинг.

Функция v1_МетодGet(Запрос)
	// Авторизация по JWT-токену
	Токен = Запрос.Заголовки.Получить("Authorization");
	КодОтвета = 200;
	
	КоличествоНаСтранице	= Запрос.ПараметрыЗапроса["c"];
	Страница				= Запрос.ПараметрыЗапроса["p"];
	
	Если Токен = Неопределено Тогда
		КодОтвета = 401;
		ДанныеДляВозврата = НСтр("ru = 'ошибка авторизации (токен не указан)'");
	ИначеЕсли СтраницаНеСуществует(Страница,КоличествоНаСтранице) Тогда
		КодОтвета = 404;
		ДанныеДляВозврата = НСтр("ru = 'отсутствует страница'");
	Иначе
		ДанныеДляВозврата	= СобратьНоменклатурыПоПараметрам(Страница,КоличествоНаСтранице);				
	КонецЕсли;				
	
	JSONСтрока		= СформироватьJSONСтроку(ДанныеДляВозврата);
	Ответ	= СформироватьОтвет(КодОтвета,JSONСтрока);	
	
	Возврат Ответ;
КонецФункции

Функция СформироватьJSONСтроку(ВходныеДанные)
	// Переводим нужные данные в формат JSON
	ЗаписьJSON = Новый ЗаписьJSON;
	ЗаписьJSON.УстановитьСтроку();  
	ЗаписатьJSON(ЗаписьJSON, ВходныеДанные);            
	JSONСтрока = ЗаписьJSON.Закрыть();
	
	Возврат JSONСтрока;
КонецФункции

Функция СформироватьОтвет(КодОтвета,JSONСтрока)
	// Формируем ответ
	Ответ = Новый HTTPСервисОтвет(КодОтвета);
	Ответ.Заголовки.Вставить("Content-Type", "text/html; charset=utf-8");
	Ответ.УстановитьТелоИзСтроки(JSONСтрока);
	
	Возврат Ответ;
КонецФункции

Функция СобратьНоменклатурыПоПараметрам(p,c) 
	// Создаем запрос который вернет нам список номенклатуры по параметрам
	Запрос = Новый Запрос("ВЫБРАТЬ
	|	Номенклатура.Наименование КАК name,
	|	Номенклатура.ЕдиницаИзмерения КАК unit,
	|	Номенклатура.Ссылка КАК Ссылка,
	|	АВТОНОМЕРЗАПИСИ() КАК НомерЗаписи
	|ПОМЕСТИТЬ ВТ_ВсяНоменклатураСНомерами
	|ИЗ
	|	Справочник.Номенклатура КАК Номенклатура
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ ПЕРВЫЕ _&КоличествоНаСтранице_
	|	ВТ_ВсяНоменклатураСНомерами.name КАК name,
	|	ВТ_ВсяНоменклатураСНомерами.unit КАК unit,
	|	ВТ_ВсяНоменклатураСНомерами.Ссылка КАК Ссылка
	|ИЗ
	|	ВТ_ВсяНоменклатураСНомерами КАК ВТ_ВсяНоменклатураСНомерами
	|ГДЕ
	|	ВТ_ВсяНоменклатураСНомерами.НомерЗаписи >= &Страница
	|
	|УПОРЯДОЧИТЬ ПО
	|	ВТ_ВсяНоменклатураСНомерами.НомерЗаписи");
	 	
	Запрос.Текст = СтрЗаменить(Запрос.Текст,"_&КоличествоНаСтранице_",с);
    Запрос.УстановитьПараметр("Страница",p*c);	// номер страницы
	
	РезультатЗапроса = Запрос.Выполнить();
	
	МассивВозврата = Новый Массив;
	
	Если РезультатЗапроса.Пустой() Тогда
		// В ТЗ ничего нет про случай когда по параметрам ничего не нашлось
		// в этом случае вернем пустой массив
	Иначе
		Выборка = РезультатЗапроса.Выбрать();
		
		Пока Выборка.Следующий() Цикл
			// Собираем данные для возврата
			СтрокаСтруктура	= Новый Структура("uid,name,unit");
			ЗаполнитьЗначенияСвойств(СтрокаСтруктура,Выборка);
			СтрокаСтруктура.uid = XMLСтрока(Выборка.Ссылка);	
			МассивВозврата.Добавить(СтрокаСтруктура);	
		КонецЦикла;
	КонецЕсли;
	
	Возврат МассивВозврата;
КонецФункции

Функция СтраницаНеСуществует(Страница,КоличествоНаСтранице)
	Запрос = Новый Запрос("ВЫБРАТЬ
	|	Номенклатура.Ссылка КАК Ссылка,
	|	АВТОНОМЕРЗАПИСИ() КАК НомерЗаписи
	|ПОМЕСТИТЬ ВТ_ВсяНоменклатураСНомерами
	|ИЗ
	|	Справочник.Номенклатура КАК Номенклатура
	|ГДЕ
	|	Номенклатура.Страница = &Страница
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ
	|	ВТ_ВсяНоменклатураСНомерами.Ссылка КАК Ссылка
	|ИЗ
	|	ВТ_ВсяНоменклатураСНомерами КАК ВТ_ВсяНоменклатураСНомерами
	|ГДЕ
	|	ВТ_ВсяНоменклатураСНомерами.НомерЗаписи >= &Страница");
	Запрос.УстановитьПараметр("Страница",Страница*КоличествоНаСтранице);
	
	РезультатЗапроса = Запрос.Выполнить();
	
	Если РезультатЗапроса.Пустой() Тогда
		Возврат Истина;
	Иначе
		Возврат Ложь;
	КонецЕсли;
КонецФункции

Вот и ещё около 30 минут потрачено, переходим к требованию 3.

Что бы выполнить требование три нужно разобраться что такое OpenAI и познакомится со swagger

Заходим в swagger и пишем там описание, какой-то автоматизации этого процесса из 1с я не знаю.

Полученный результат можно посмотреть по ссылке описание api

Интерфейс swagger и предварительный результат полученного описания API swagger описание api в формате openAI

На этом все, критика приветствуется.