Jetbrains golang создание проекта

Обновлено: 07.07.2024

Привет, Хабр! Представляю вашему вниманию перевод статьи "How to build your first web application with Go" автора Ayooluwa Isaiah.

Это руководство к вашему первому веб-приложению на Go. Мы создадим новостное приложение, которое использует News API для получения новостных статей по определенной теме, и развернём его на продакшн сервере в конце.

Вы можете найти полный код, используемый для этого урока в этом GitHub репозитории.

Требования

Единственное требование для этого задания — чтобы на вашем компьютере был установлен Go, и вы немного знакомы с его синтаксисом и конструкциями. Версия Go, которую я использовал при создании приложения, также является самой последней на момент написания: 1.12.9. Чтобы просмотреть установленную версию Go, используйте команду go version .

Если вы считаете это задание слишком сложным для вас, перейдите к моему предыдущему вводному уроку по языку, который должен помочь вам освоиться.

Итак, начнем!

Клонируем репозиторий стартовых файлов на GitHub и cd в созданный каталог. У нас есть три основных файла: В файле main.go мы напишем весь код Go для этого задания. Файл index.html — это шаблон, который будет отправлен в браузер, а стили для приложения находятся в assets/styles.css .

Создадим базовый веб-сервер

Давайте начнем с создания базового сервера, который отправляет текст «Hello World!» в браузер при выполнении запроса GET к корню сервера. Измените ваш файл main.go так, чтобы он выглядел следующим образом:

Затем скомпилируйте и выполните код, который вы только что написали:

Brave browser showing Hello World text

Шаблоны в Go

Давайте рассмотрим основы шаблонизации в Go. Если вы знакомы с шаблонами на других языках, это должно быть достаточно просто для понимания.

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

Go предоставляет две библиотеки шаблонов в своей стандартной библиотеке: text/template и html/template . Оба предоставляют один и тот же интерфейс, однако пакет html/template используется для генерации HTML-вывода, который защищен от инъекций кода, поэтому мы будем использовать его здесь.

Импортируйте этот пакет в ваш файл main.go и используйте его следующим образом:

tpl — переменная уровня пакета, которая указывает на определение шаблона из предоставленных файлов. Вызов template.ParseFiles анализирует файл index.html в корне каталога нашего проекта и проверяет его на валидность.

Мы оборачиваем вызов template.ParseFiles в template.Must , чтобы код вызывал панику при возникновении ошибки. Причина, по которой мы паникуем здесь вместо того, чтобы пытаться обработать ошибку, заключается в том, что нет смысла продолжать выполнение кода, если у нас невалидный шаблон. Это проблема, которая должна быть устранена перед попыткой перезапустить сервер.

В функции indexHandler мы выполняем созданный ранее шаблон, предоставляя два аргумента: куда мы хотим записать выходные данные и данные, которые мы хотим передать в шаблон.

В приведенном выше случае мы записываем выходные данные в интерфейс ResponseWriter и, поскольку у нас нет никаких данных для передачи в наш шаблон в настоящее время, в качестве второго аргумента передается nil .

Остановите запущенный процесс в вашем терминале с помощью Ctrl-C и запустите его снова с помощью go run main.go , затем обновите ваш браузер. Вы должны увидеть текст «News App Demo» на странице, как показано ниже:

Brave browser showing News App Demo Text

Добавляем панель навигации на страницу

Замените содержимое тега <body> в вашем файле index.html, как показано ниже:

Затем перезагрузите сервер и обновите ваш браузер. Вы должны увидеть что-то похожее на это:

Browser showing unstyled navigation bar

Работа со статическими файлами

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

Но необходимость объявлять явные обработчики для всех наших статических файлов нереальна и не может масштабироваться. К счастью, мы можем создать один обработчик для обслуживания всех статических ресурсов.

Первое, что нужно сделать, — создать экземпляр объекта файлового сервера, передав каталог, в котором находятся все наши статические файлы:

Далее нам нужно указать нашему маршрутизатору использовать этот объект файлового сервера для всех путей, начинающихся с префикса /assets/ :

Теперь всё вместе:

Перезагрузите сервер и обновите браузер. Стили должны включиться, как показано ниже:

Brave browser showing styled navigation bar

Создаем роут /search

Давайте создадим роут, который обрабатывает поисковые запросы для новостных статей. Мы будем использовать News API для обработки запросов, поэтому вам нужно зарегистрироваться для получения бесплатного ключа API здесь.

Этот маршрут ожидает два параметра запроса: q представляет запрос пользователя, а page используется для пролистывания результатов. Этот параметр page является необязательным. Если он не включен в URL, мы просто предположим, что номер страницы результатов имеет значение «1».

Добавьте следующий обработчик под indexHandler в ваш файл main.go :

Приведенный выше код извлекает параметры q и page из URL-адреса запроса и выводит их оба в терминал.

Затем зарегистрируйте функцию searchHandler в качестве обработчика пути /search , как показано ниже:

Не забудьте импортировать пакеты fmt и net/url сверху:

Теперь перезапустите сервер, введите запрос в поле поиска и проверьте терминал. Вы должны увидеть ваш запрос в терминале, как показано ниже:

Создаём модель данных

Когда мы делаем запрос к конечной точке News API/everything , мы ожидаем ответ json в следующем формате:

Чтобы работать с этими данными в Go, нам нужно сгенерировать структуру, которая отражает данные при декодировании тела ответа. Конечно, вы можете сделать это вручную, но я предпочитаю использовать веб-сайт JSON-to-Go, который делает этот процесс действительно простым. Он генерирует структуру Go (с тегами), которая будет работать для этого JSON.

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

Brave browser showing JSON to Go tool

Я сделал несколько изменений в структуре AutoGenerated , отделив фрагмент Articles в его собственную структуру и обновив имя структуры. Вставьте следующее ниже объявление переменной tpl в main.go и добавьте пакет time в ваш импорт:

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

Поэтому мы используем теги поля структуры, такие как json:"id" , чтобы явно отобразить поле структуры в поле JSON, как показано выше. Это также позволяет использовать совершенно разные имена для структурного поля и соответствующего поля json, если это необходимо.

Наконец, давайте создадим другой тип структуры для каждого поискового запроса. Добавьте это ниже структуры Results в main.go :

Эта структура представляет собой каждый поисковый запрос, сделанный пользователем. SearchKey — это сам запрос, поле NextPage позволяет пролистывать результаты, TotalPages — общее количество страниц результатов запроса, а Results — текущая страница результатов запроса.

Отправляем запрос по News API и рендерим результаты

Теперь, когда у нас есть модель данных для нашего приложения, давайте продолжим и сделаем запросы к News API, а затем отрендерим результаты на странице.

Поскольку для News API требуется ключ API, нам нужно найти способ передать его в нашем приложении без жесткого кодирования в коде. Переменные среды являются распространенным подходом, но я решил использовать вместо них флаги командной строки. Go предоставляет пакет flag , поддерживающий базовый анализ флагов командной строки, и это то, что мы собираемся использовать здесь.

Сначала объявите новую переменную apiKey под переменной tpl :

Затем используйте её в функции main следующим образом:

Здесь мы вызываем метод flag.String() , который позволяет нам определять строковый флаг. Первый аргумент этого метода — имя флага, второй — значение по умолчанию, а третий — описание использования.

После определения всех флагов вам нужно вызвать flag.Parse() , чтобы фактически проанализировать их. Наконец, так как apikey является обязательным компонентом для этого приложения, мы обеспечиваем аварийное завершение программы, если этот флаг не установлен при выполнении программы.

Убедитесь, что вы добавили пакет flag в свой импорт, затем перезапустите сервер и передайте требуемый флаг apikey , как показано ниже:

Замените два вызова метода fmt.Println() в конце функции searchHandler следующим кодом:

После этого мы конвертируем переменную page в целое число и присваиваем результат полю NextPage переменной search . Затем мы создаем переменную pageSize и устанавливаем ее значение равным 20. Эта переменная pageSize представляет количество результатов, которые API новостей будет возвращать в своем ответе. Это значение может находиться в диапазоне от 0 до 100.

Затем мы создаем конечную точку с помощью fmt.Sprintf() и делаем запрос GET к ней. Если ответ от News API не 200 OK, мы вернем клиенту общую ошибку сервера. В противном случае тело ответа парсится в search.Results .

Затем мы вычисляем общее количество страниц путем деления поля TotalResults на pageSize . Например, если запрос возвращает 100 результатов, а мы одновременно просматриваем только 20, нам нужно будет пролистать пять страниц, чтобы просмотреть все 100 результатов по этому запросу.

После этого мы рендерим наш шаблон и передаем переменную search в качестве интерфейса данных. Это позволяет нам получать доступ к данным из объекта JSON в нашем шаблоне, как вы увидите.

Прежде чем перейти к index.html , обязательно обновите ваши импорты, как показано ниже:

Давайте продолжим и отобразим результаты на странице, изменив файл index.html следующим образом. Добавьте это под тегом <header> :

Чтобы получить доступ к полю структуры в шаблоне, мы используем оператор точки. Этот оператор ссылается на объект структуры (в данном случае search ), а затем внутри шаблона мы просто указываем имя поля (как > ).

Блок range позволяет нам перебирать слайс в Go и выводить некоторый HTML для каждого элемента в слайсе. Здесь мы перебираем слайс структур Article , содержащихся в поле Articles , и выводим HTML на каждой итерации.

Перезагрузите сервер, обновите браузер и выполните поиск новостей по популярной теме. Вы должны получить список из 20 результатов на странице, как показано на скрине ниже.

Browser showing news listings

Сохраняем поисковый запрос в инпуте

Обратите внимание, что поисковый запрос исчезает из ввода, когда страница обновляется с результатами. В идеале запрос должен сохраняться до тех пор, пока пользователь не выполнит новый поиск. Вот как Google Search работает, например.

Перезапустите браузер и выполните новый поиск. Поисковый запрос будет сохранен, как показано ниже:


Форматируем дату публикации

Если вы посмотрите на дату в каждой статье, вы увидите, что она плохо читаема. Текущий вывод показывает, как News API возвращает дату публикации статьи. Но мы можем легко изменить это, добавив метод в структуру Article и используя его для форматирования даты вместо использования значения по умолчанию.

Давайте добавим следующий код чуть ниже структуры Article в main.go :

Здесь новый метод FormatPublishedDate создан в структуре Article , и этот метод форматирует поле PublishedAt в Article и возвращает строку в следующем формате: 10 января 2009 .

Чтобы использовать этот новый метод в вашем шаблоне, замените .PublishedAt на .FormatPublishedDate в вашем файле index.html . Затем перезагрузите сервер и повторите предыдущий поисковый запрос. Это выведет результаты с правильно отформатированным временем, как показано ниже:

Brave browser showing correctly formatted date

Выводим общее количество результатов

Все, что вам нужно сделать, это добавить следующий код как дочерний элемент .container , чуть выше элемента .search-results в вашем файле index.html :

Шаблоны Go поддерживают несколько функций сравнения, некоторые из которых используются выше. Мы используем функцию gt , чтобы проверить, что поле TotalResults структуры Results больше нуля. Если это так, общее количество результатов будет напечатано в верхней части страницы.

Browser showing no results found message

После этого сделайте еще один поисковый запрос на этот раз с популярной темой. Количество результатов будет выведено вверху страницы, как показано ниже:

Browser showing results count at the top of the page

Пагинация

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

Сначала добавим кнопку Next внизу результатов, если последняя страница результатов еще не достигнута. Чтобы определить, была ли достигнута последняя страница результатов, создайте этот новый метод ниже объявления структуры Search в main.go :

Этот метод проверяет, больше ли поле NextPage , чем поле TotalPages в экземпляре Search . Чтобы это работало, нам нужно увеличивать NextPage каждый раз, когда отображается новая страница результатов. Вот как это сделать:

Наконец, давайте добавим кнопку, которая позволит пользователю перейти на следующую страницу результатов. Этот код должен быть помещен ниже .search-results в вашем файле index.html .

Пока последняя страница для этого запроса не была достигнута, кнопка Next будет отображаться в нижней части списка результатов.

Как видите, href ссылки указывает на маршрут /search и сохраняет текущий поисковый запрос в параметре q , используя значение NextPage в параметре page .

Давайте добавим кнопку Previous. Эту кнопку следует отображать только в том случае, если текущая страница больше 1. Чтобы сделать это, нам нужно создать новый метод CurrentPage() в Search , чтобы реализовать это. Добавьте это ниже метода IsLastPage :

Текущая страница просто NextPage - 1 , за исключением случаев, когда NextPage равен 1. Чтобы получить предыдущую страницу, просто вычтите 1 из текущей страницы. Следующий метод делает именно это:

Таким образом, мы можем добавить следующий код для отображения кнопки Previous, только если текущая страница больше 1. Измените элемент .pagination в вашем файле index.html следующим образом:

Теперь перезагрузите сервер и сделайте новый поисковый запрос. У вас должно получиться пролистать результаты, как показано ниже:

Показываем текущую страницу

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

Для этого нам нужно всего лишь изменить наш файл index.html следующим образом:

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

Browser showing current page

Деплоим на Heroku

Теперь, когда наше приложение полнофункционально, давайте продолжим и развернем его в Heroku. Зарегистрируйте бесплатную учетную запись, затем перейдите по этой ссылке, чтобы создать новое приложение. Укажите для приложения уникальное имя. Я назвал приложение freshman-news.

Затем следуйте инструкциям здесь, чтобы установить интерфейс командной строки Heroku на свой компьютер. Затем выполните команду heroku login в терминале, чтобы войти в свою учетную запись Heroku.

Убедитесь, что вы инициализировали git-репозиторий для своего проекта. Если нет, запустите команду git init в корне каталога вашего проекта, а затем выполните команду ниже, чтобы установить heroku в качестве удаленного git-репозитория. Замените freshman-news названием вашего приложения.

Затем создайте Procfile в корневом каталоге вашего проекта ( touch Procfile ) и вставьте следующее содержимое:

После этого укажите репозиторий GitHub для своего проекта и версию Go, которую вы используете, в своем файле go.mod , как показано ниже. Создайте этот файл, если он еще не существует, в корне проекта.

Перед развертыванием приложения перейдите на вкладку Settings на панели инструментов Heroku и нажмите Reveal Config Vars. Нам нужно установить переменную среды NEWS_API_KEY, чтобы она могла быть передана в бинарный файл при запуске сервера.

Heroku config variables

Наконец, сделайте коммит своего кода и сделайте пуш в Heroku с помощью следующих команд:

Заключение

В этой статье мы успешно создали приложение News и обучились основам использования Go для веб-разработки. Мы также изучили, как развернуть готовое приложение в Heroku.

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

Пару месяцев назад я начал писать на Go так же известным, как Golang. И не только из-за их потрясающего логотипа. Основная причина была в том, что я хотел, чистую железяку на моем Raspberry Pi, а так же кроссплатформенность в паре с легкостью установки. Среди других причин были простота создания на Go асинхронного кода с помощью Go методов и уникальный подход к синхронизации каналов между подпрограммами (потоками) посредствам go routines.

С тех пор, как GO был выпущен в 2012 году, я много читал о нем и что ж, пришло время по-настоящему замарать руки и попробовать использовать его для своих задач.

Однако любопытно, продолжим .

Что же из себя представляет GO?

Go - это опен сорсный язык программирования , который позволяет легко создавать простое, надежное и эффективное программное обеспечение. Разрабатывался он внутри компании Google и на 2018 год уже являлся одним из самых быстроразвивающихся и адаптированных языков программирования. Первый релиз языка появился в марте 2012 года. А не так давно, начиная с выпуска Go 1.11, у него появилась поддержка модулей и управлять зависимостями стало немного удобнее.

Необходимые настройки среды

Для начала нужно все правильно настроить. Есть простой способ установить мою библиотеку с помощью Chocolatey.

В Windows мы используем Chocolatey в Powershell для установки Go и vscode…

С установленным Go и vscode у нас есть все, что нужно для начала.

Так как я использую Git bash на все случаи жизни, я запускаю следующую команду Visual Studio Code из Git Bash, чтобы установить go расширение. Если хотите, вы можете просто установить расширение из самого vscode.

Вот мы и поставили Go расширение в visualstudio, так что теперь у нас есть все для приятного кодинга.

Где найти отличные ресурсы и материалы по GO?

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

Создаем первый проект

Для того, чтобы начать на Go новый проект, мы сначала создаем пустую папку. Затем мы прописываем в этой папке команду go modules init, чтобы инициализировать модули Go. Модули используются для зависимостей.

Синтаксис

В Go мы определяем функцию, используя ключевое слово func.

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

Все переменные, функции, структуры, которые начинаются с верхнего регистра в Go являются публичными. А все переменные, функции, структуры, начинающиеся со строчной буквы, являются частными. Кроме того, как вы наверное уже заметили в примере, определения типов идут за именем переменной. Поместив оператор импорта поверх файла вы можете импортировать все необходимые пакеты. И последнее, но не менее важное: каждая программа go должна иметь хотя бы один main пакет.

Этот пакет fmt предоставляет нам несколько полезных функций, например строки шаблонов, которые удобно использовать для построения строки с использованием некоторых переменных.. Более того, в примере мы видим, что возвращаемый тип для функции упоминается в конце ее определения. Более подробно читайте о пакете fmt в документации.

Теперь у нас есть пустой проект, и к тому же мы уже немного знаем о синтаксисе, чтож, начнем! Открываем эту папку в vscode.

Сначала мы добавляем новый файл в нашу папку, называем ее main.go . Затем добавим тот код, который мы рассмотрели выше.

Теперь с помощью этого кода мы можем запустить наше приложение. Используя следующую команду в командной строке.

Можете также прогнать этот код в Go playground.

Тестирование

Чтобы добавить тесты в go, просто добавьте файл main_test.go. Добавим функцию проверяющую метод sayHi. Сигнатура методов тестирования всегда ДОЛЖНА быть TestXxx(t *testing.T). Первый X всегда должен быть в верхнем регистре.

Теперь, чтобы запустить наш тест, мы сделаем в командной строке следующее. Обратите внимание, что я запускаю все тесты из всех файлов и подпапок в моем проекте таким способом ./.

Пожалуйста, не бойтесь пробовать, изменяйте реализацию, и снова запустите тест, чтобы увидеть, как тесты пройдут неудачно. Для запуска с code coverage запустите такие тесты.

Чтобы подробнее ознакомится, пожалуйста, читайте документацию о testing package.

Компилируем и выполняем

Самым простым способом создать исполняемый файл будет:

Это команда создаст нам исполняемый файл Windows, как будто мы на Windows. Вы можете просто вызвать исполняемый файл и увидеть тот же результат, что мы имели при вызове go run main.go. Если мы хотим получить более подробный вывод и посмотреть, что происходит за под капотом, можно использовать -x опцию -в go build. А как нам скомпилировать один и тот же код для Linux или Raspberry Pi?

Чтобы запустить этот бинарник в Linux, не забудьте использовать chmod +x, а затем просто вызвать с помощью ./hello-world

Raspberry Pi 3 имеет архитектуру ARM v7, которую можно скомпилировать следующим образом. ПРИМЕЧАНИЕ: все это мы можем сделать с Windows.

Для запуска бинарника сделайте все то же самое, что и на любом другом компьютере с Linux chmod +x, а затем ./hello-world для запуска вашего приложения.

Резюмируя

Я знаю, что это очень простое приложение и оно не несет практической пользы, но, по крайней мере, вы уже, как минимум, настроили свою среду разработки и приобрели небольшой практический опыт в написании первых строк кода на Go. Вы уже также знаете, как писать тесты. Это будет хорошей основой для написания качественного кода. Более интересные вещи, такие как go routines, я хотел бы оставить для нового поста в блоге.

И последнее, но не менее важное: я хотел бы поделиться с вами своим первым приложением на Go. Это интеграция с термостатом Nest, который я запускаю на своем Raspberry Pi, чтобы собрать данные о температуре и отобразить их в хорошем веб-приложении на React. Только не забудьте зарегистрироваться в рабочем пространстве Gophers Slack.

Golang

При запуске нового проекта самые большие трудности у меня всегда вызывала его настройка. Всегда стараешься сделать её «идеальной»:

  • используешь лучшую структуру каталогов, чтобы всё было легко найти и импортирование происходило без проблем;
  • настраиваешь все команды так, чтобы нужные действия выполнялись в один клик или с вводом одной команды;
  • находишь лучший инструмент контроля качества кода, средство форматирования, среду тестирования для используемого в проекте языка и библиотеки…

Этот список можно продолжать и продолжать, и всё равно до идеальной настройки будет ещё далеко… Но, по моему скромному мнению, эта настройка для Golang просто лучшая!

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

Структура каталогов

Первым делом обратимся к структуре каталогов нашего проекта. Здесь у нас несколько файлов верхнего уровня и четыре каталога:

  • pkg — это пакет Go, который содержит только строку версии global. Меняется на версию из хэша текущей фиксации при проведении сборки;
  • config — конфигурационный каталог, который содержит файлы со всеми необходимыми переменными среды. Вы можете использовать любой тип файла, но я бы рекомендовал файлы YAML: их проще читать;
  • build — в этой директории у нас все скрипты оболочки, необходимые для сборки и тестирования приложения, а также создания отчётов для инструментов анализа кода;
  • cmd — фактический исходный код. По правилам именования исходный каталог называется cmd . Внутри есть ещё один каталог с именем проекта (в нашем случае blueprint ). В свою очередь, внутри этого каталога находится main.go , запускающий всё приложение. Также здесь можно найти все остальные исходные файлы, разделённые на модули (подробнее об этом далее).

Оказывается, многие предпочитают помещать исходный код в каталоги internal и pkg . Я думаю, что это лишнее: достаточно использовать для этого cmd , где для всего есть своё место.

Помимо каталогов, есть ещё большое количество файлов, о которых мы поговорим в статье.

Модули Go для идеального управления зависимостями

В проектах Go используются самые разные стратегии управления зависимостями. Однако с версии 1.11 Go обзавёлся официальным решением. Все наши зависимости приводятся в файле go.mod , в корневом каталоге. Вот как он может выглядеть:

Вы можете спросить: «А как в этот файл включить зависимости?». Очень просто, всего одной командой:

Эта команда переустанавливает vendor каталог основного модуля для включения всех пакетов, необходимых для сборки и тестирования каждого пакета модуля исходя из состояния файлов go.mod и исходного кода Go.

Фактический исходный код и конфигурация

И вот наконец мы добрались до исходного кода. Как уже говорилось, исходный код разделён на модули. Модуль представляет собой каталог внутри исходного корневого каталога. В каждом модуле находятся исходные файлы вместе с соответствующими файлами тестов. Например:

Такая структура способствует лучшей читаемости и лёгкости сопровождения кода: он идеально разделён на части, которые проще просматривать. Что касается конфигурации, в этой настройке используем библиотеку конфигураций Go Viper, которая может иметь дело с разными форматами, параметрами командной строки, переменными среды и т.д.

Посмотрим, как мы используем этот Viper здесь. Вот пакет config :

Он состоит из единственного файла. Объявляет один struct , который содержит все переменные конфигурации и имеет одну функцию LoadConfig , которая загружает конфигурацию. Требуется путь до конфигурационных файлов, в нашем случае используем путь до каталога config , который находится в корневом каталоге проекта и содержит наши YAML файлы. И как их будем использовать? Запустим первым делом в main.go :

Простое и быстрое тестирование

Что важнее всего после кода? Тесты. Чтобы писать много хороших тестов, нужна настройка, с которой это будет делать легко. Для этого мы используем цель Makefile под названием test , которая собирает и выполняет все тесты в подкаталогах cmd (все файлы с расширением _test.go ). Эти тесты кэшируются, так что их запуск происходит только при наличии изменений в соответствующей части кода. Это очень важно: если тесты будут слишком медленными, рано или поздно вы перестанете их запускать и сопровождать. Помимо модульного тестирования, make test помогает следить за общим качеством кода, запуская с каждым тестовым прогоном gofmt и go vet . gofmt способствует правильному форматированию кода, а go vet помогает с помощью эвристических алгоритмов выявлять в коде любые подозрительные конструкции. Вот пример того, что может получиться в результате выполнения:

Запуск всегда в Docker

Многие говорят, что у них запуск невозможен в облаке, а только на компьютере. Здесь есть простое решение: всегда запускаться в контейнере docker . Делаете ли вы сборку, запускаете ли или тестируете — делайте всё это в контейнере. Кстати, что касается тестирования, make test выполняется тоже только в docker .

Посмотрим, как это происходит. Начнём с файлов Dockerfile из корневого каталога проекта: один из них для тестирования ( test.Dockerfile ), а другой — для запуска приложения ( in.Dockerfile ):

Связываем всё вместе с помощью Makefile

Долгое время Make-файлы казались мне страшными (до этого я сталкивался с ними лишь при работе с кодом C ), но на самом деле ничего страшного здесь нет, и их много где можно использовать, в том числе для этого проекта! Посмотрим, какие цели у нас здесь есть в Makefile :

Эти строчки — важная часть файла. Первая из них собирает тестовые цели, где в качестве параметра указан путь. Вторая строчка запускает тесты и выводит документацию по тестированию ПО. Оставшиеся две строчки запускают gofmt и go vet . Они собирают и выводят ошибки (если таковые имеются).

Остальные цели можно объединить в две группы: первые не так важны для нормального рабочего процесса, а вторые являются лишь частью других целей, поэтому о них можно не упоминать.

Интеграция и развёртывание ПО для идеальной разработки

Завершаем статью важной частью — процессом непрерывной интеграции и развёртывания приложений. Не буду подробно расписывать, что в нем такого — вы и сами прекрасно сможете разобраться (практически в каждой строке есть комментарий, так что всё должно быть понятно):

Но кое-что можно прояснить.

В этой сборке Travis использована сборка Matrix Build с 4 параллельными заданиями для ускорения всего процесса:

  • Сборка и тестирование: здесь мы проверяем, что приложение работает как надо;
  • SonarCloud: здесь мы генерируем отчёты о покрытии и отправляем их на сервер SonarCloud;
  • CodeClimate: здесь — как и в предыдущем задании — мы генерируем отчёты о покрытии и отправляем их, только на этот раз в CodeClimate с помощью их генератора тестовых отчётов;
  • Push to Registry: и, наконец, помещаем наш контейнер в хранилище GitHub Registry.

Заключение

Надеюсь, эта статья поможет вам в ваших будущих разработках кода на Go. Все подробности изложены в репозитории.

В следующей части узнаем, как на базе этого макета проекта, который мы сегодня выстроили, с лёгкостью создавать интерфейсы RESTful API, тестировать с базой данных в памяти, а также настраивать крутую документацию (а пока можно подсмотреть в ветке rest-api репозитория). ?

enter image description here

Я настроил golang developing envionemnt с помощью idea (13.1 community edition). Кажется, SDK распознается. Однако я не смог создать файл GO, щелкнув правой кнопкой мыши "создать" под исходной папкой. (Пункт " go " серым цветом) В настоящее время я должен вручную установить расширение файла в ".go " и редактировать файл, но автозаполнение в порядке. Это существует только на моем Mac (с версией 10.9.4) Я установил режим доступа к каталогу GOPATH в 777, но все еще не работает. Это отлично работает на windows7. Так что мне делать ?

enter image description here

вот как это выглядит в windows

enter image description here

и это то, что выглядит в /Users/Tom/Go

enter image description here

спасибо VonC, однако, это не работает. Не знаю, в чем причина. Это параметр envionment с помощью GOCODE Это несколько шаги! Шаг 1

step 2

step3

step4

step5

this is envionment seting

mac and windows not exactly at this step

кстати, я заметил, что есть разница с mac и windows при создании нового проекта Go на этом шаге платформа windows покажет "Project sdk", а mac-нет.

Читайте также: