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

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

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

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

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

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

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

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

Требования уровень 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

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