четверг, 30 августа 2018 г.

A programmer: JavaScript #6

Сегодня немного о вводе, поиске и выводе (пока опять в консоль). Для того, чтобы искать и выводить что-либо из базы данных, надо это сначала туда ввести. В прошлый раз мы сделали только тестовое добавление элемента. Сегодня - множественное добавление. Для этого сначала подготовим небольшой файл с именем persons.json:


Это набор объектов, который мы вставим в нашу базу данных. Делается это вот так:


В строке 5 мы подключаем наш файл, в строке 10 подключаем нашу коллекцию, в строке 15 выводим результат:


Поиск осуществляется с помощью специального объекта, которому присваивается значение collection.find():


В строке 10 мы создаем этот объект.
В строке 12 на нем вызываем функцию, которая возвратит данные, приведенные к массиву.
В строке 13 внутри этой функции осуществляем поиск по нашей базе данных, задав условие поиска.
В строке 15 выводим найденный результат:


Как видим, пока всё просто, главное - не забыть перед этим запустить сам сервер и указать правильный путь к хранилищу данных :).

вторник, 28 августа 2018 г.

A programmer: JavaScript #5

Грусть-печалька, с одной стороны, она же большая радость, с другой стороны, а именно: я нашел классное описание всего того, что я хотел сделатьь и описать здесь. Печалька потому, что уже кто-то это сделал, а радость - потому что уже кто-то это сделал, и я могу почитать и лучше понять! Вот такая вот диалектика, впрочем не в первый раз. А сам ресурс вот - спасибо автору:

 Building a Simple CRUD Application with Express and MongoDB

Итак, мы остановились на том, что программа обрабатывает наш POST-запрос и выводит то, что ввёл пользователь, в консоль. А нам надо в базу данных. Значит, продолжаем:

8. Устанавливаем MongoDB в проект:

npm install mongodb --save

9. Теперь мы можем использовать MongoClient - основной класс для работы с базами данных:



Комментарии не очень видны, поэтому ещё раз:

  • в строке 1 мы подключили модуль mobngodb и сразу взяли из него MongoClient;
  • в строке 2 мы указали url для нашей базы данных - помните, мы говорили, что 27017 - это порт, который используется для работы с базой данных?;
  • в строке 4 мы создаем соединение с указанным url, если подключение произошло без выброса ошибки (err), то мы имеем в нашем распоряжении объект (db) для работы с базой данных (оногда его обозначают client);
  • в строке 5 мы через него получаем нашу базу данных (users), которая теперь внутри программы выступает как collection;
  • в 7 строке мы вставляем в базу данных тестовый объект (документ), созданные в строке 6 (просто чтобы увидеть, что у нас всё работает);
  • в строке 9 проверяем, нет ли ошибки;
  • в строке 13 выводим результат в консоль;
  • в строке 15 закрываем соединение.

В итоге в консоли видим такой вывод:


Здесь _id - это уникальный идентификатор элемента коллекции, который создается автоматически.

Как видим - всё работает! Собственно говоря, мы могли бы не добвалять ввод объекта в базу данных, а просто подключиться, проверить подключение и выйти. Тогда всё выглядело бы ещё проще:


А ещё один хороший ресурс вот:

Ещё один хороший ресурс

пятница, 24 августа 2018 г.

A programmer: JavaScript #4

Вчера написал мало, потому что случился затык с тем, что те уроки, которые я слушал (а я предпочитаю видеоуроки), были слишком разные: в одном запускали сервер, но он работал только с консолью; в другом дошли до POST-запросов, выводили их на страницу, но не в базу данных; в третьем работали только с базой данных в собственной консоли; в четвертом делали всё, что нужно, но подключали дополнительный пакет mongoose, который часть необходимой работы делал неочевидной. В итоге я запутался и решил сделать всё сначала, самостоятельно, по возможности без дополнительных пакетов. Задача приложения - показывать пользователю страницу с формой и собирать введенные им данные в базу данных. Сегодня - первая часть.

1. Поскольку всё с самого начала, то создаём папку с проектом и в консоли переходим в неё.

2. С помощью комманды npm init создаём package.json.

3. Создаём файл index.js и пишем в нём сервер - такой, который писали в первом посте про JavaScript. Кстати там мой код (а не из Википедии), который должен создавать и запускать веб-сервер, не должен работать, потому что там не указан адрес '127.0.0.1' - простите, не проверил. Правильный код вот:


Если всё в порядке, в консоли видим Web-server is working, а в браузере по адресу 127.0.0.1:3000 - HTML.

4. Как показали беглые разыскания, совсем без дополнительных пакетов ничего не получится. Поэтому решил всё-таки вернуться к express, а с тем, как работать без него, разберусь потом. Для начала его надо установить: npm install express. Тот же самый сервер с использованием express выглядит так:


Единственное отличие - он пока ничего не показывает в браузере.

5. Чтобы исправить это, установим и укажем шаблонизатор - ejs. Создадим папку views, в которой будут лежать шаблоны. Далее - создадим шаблоны (файлы с расширением .ejs вместо .html - я о них упоминал уже) и сделаем маршрутизацию. Теперь наш код выглядит так:


и отображает страницу /views/404.ejs

6. Это, разумеется, тренировка - давайте всё-таки переименуем файл в form.ejs. Теперь зададим код для шаблона, например, такой:

Выглядит вот так (стили и прочее я не прикручивал - только функционал):

7. Добавим обработчик для POST-запроса (как в прошлом посте) и сделаем вывод, пока что в консоль. Для этого просто добавим в обработчик строку console.log(req.body); Ура!

Не работает... Сервер запускается, страница ввода видна, но в обработчик не заходит. Почему?

Проверяем всё. Оказывается, забыли добавить в код формы указание на метод. Добавляем:


Не работает. Хотя в обработчик запроса уже заходит, но в консоли показывает пустое тело {}. То есть не парсит. Почему?

Потому что в строки, где описывается ввод имейла и пароля не добавили атрибут name. Добавляем:

name="email"
name="pass"

Проверяем - работает!

Итак - повторение пройденного получилось в целом неплохим. На сегодня хватит, пожалуй.

A programmer: JavaScript #3

Сегодня немного о базе даных MongoDB и обработке POST-запроса. В прошлый раз мы просто показывали пользователю определенную страницу в зависимости от того, что он нажал или ввел в адресной строке. Но часто бывает необходимо сохранить какую-то информацию, которую пользователь вводит на сайте. Для этого используют базы данных. Базы данных бывают реляционные и нереляционные. Реляционные - это те, которые предполагают отношения между своими составными частями, нереляционные - простые наборы (коллекции) документов, в которых сами документы могут быть самыми разными. MongoDB - нереляционная база данных, и выбрана из соображений простоты.



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

mongod.exe - сервер базы данных и
mongo.exe - консольный терминал для работы с базой данных

Обычно (если у вас Windows и вы не меняли путь для установки) она имеет приблизительно такой вид:

C:\Program Files\MongoDB\Server\4.0\bin

Далее надо запустить сервер. Для этого можно просто набрать mongod, но если вас не устраивает заданное по умолчанию место хранения данных (где именно оно находится по умолчанию - надо ещё смотреть в настройках), можно указать собственное (не забудьте предварительно эту папку создать):

mongod --dbpath <адрес желаемого места хранения данных>

Запустив это, вы увидите много букв, среди которых должно быть сообщение о том, что сервер запущен на порте 27017. Далее вы можете запустить mongo.exe и работать в коммандной строке терминала, а можете установить и использовать графический интерфейс. Чтобы всё это работало в нашем проекте, надо установить соответствующие пакеты (например, через npm install <имя пакета>) - mongod и mongodb. Проследите, чтобы они появились в разделе dependencies файла package.json. Теперь можно работать - у вас есть сервер базы данных и инструменты для работы с ним.

Но для начала следует отвлечься на одну важную деталь. Обычно пользователь вводит сразу несколько "кусочков" информации на странице и только потом отправляет всё сразу на сервер.


Очевидно, что GET-запрос для этого не подходит. Для этого нужен POST-запрос - он обрабатывает формы. Естественно, для этого вы должны разместить соответствующий код с формой у себя на странице (код для указанной выше формы можно посмотреть на bootstrap'е). Обработчик POST-запроса в коде программы будет выглядеть следующим образом (на всякий случай отмечу, что это только засть кода из файла):


Здесь мы видим подключение модуля body-parser и использование его для того, чтобы распарсить (определенным образом считать) то, что введено в форму. В качестве вывода имеем итоговую страницу (about-success), куда передаются на вывод эти же данные (req.body).

Теперь нам надо то же самое (считанные данные, которые ввел пользователь) передавать не на вывод, а в базу данных. Но об этом - в следующий раз.

четверг, 23 августа 2018 г.

A programmer: JavaScript #2

Для начала небольшой disclaimer.

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

Во-вторых, прошлый пост получился большой и много о чём. Поэтому придется внести некоторую структуру в излагаемое. Итак, кроме моих мотивов, связанных с изучением JavaScript'a, содержательно в прошлом посте речь шла о NodeJS и создании веб-сервера.

Соответственно, в этом посте - о маршрутизации и верстке.


Умное слово "маршрутизация" в данном конкретном случае означает то, что мы определяем то, что программа должна показывать пользователю, если он совершил то или иное действие. Собственно, в прошлом посте об этом уже сказано. Там мы использовали объект app для того, чтобы работать с библиотекой express. Если бы мы не использовали  express, наша маршрутизация выглядела бы иначе:


То есть мы бы указывали маршрут через проверку условий if-else, а результат был бы тот же. Просто подключив express, мы написали отдельные обработчики, что, мне кажется, удобнее.

В чем ещё есть отличия с примером из прошлого поста? В том, что мы подключили модуль fs - он обеспечивает ввод-вывод данных. Как я говорил, можно подключить и собственный модуль. Тогда пришлось бы написать:

const some_module = require('/some_module');

Слеш перед именем модуля означает, что модуль должен находиться в папке с проектом. Другие модули загружаются в папку node_modules. Для того, чтобы из собственного модуля, который часто представляет собой просто файл, сделать доступными вовне те или иные переменные или функции, надо написать (при этом и функцию можно присвоить переменной и вызывать её через неё):

module.exports.some_value = some_value;

Но вернемся к маршрутизации и верстке. Итак, пусть мы написали обработчики, которые должны показывать нужные страницы в зависимости от запроса. Возникает вопрос: а где же страницы? Они лежат в папке с проектом. Там могут лежать сами страницы - например, какой-нибудь index.html, а могут - шаблоны (обычно в папке /views). Поскольку мы работаем с express, то шаблоны у нас - это файлы с расширением .ejs, которые выглядят, например, вот так:


Похоже на обычный html-файл - почему это шаблон? Потому что в нём есть исполняемый функционал. Он заключен в соответствующие скобки <% ... %> или <%= ... %> (в первом случае имеется в виду некоторое действие, во втором - просто вывод заданного параметра). Естественно, что выводимые параметры должны быть переданы шаблону в файле с маршрутизацией. В нашем примере - это параметр newsId, а также объект obj с параметрами  title, id и массивом paragraphs.

Здесь также видим, что командой include подключается файл header.ejs, находящийся не в самой папке /views, а в подпапке /blocks (строка 11). А в 8 строке подключается файл со стилями, который находится по адресу /public/css. Собственно, в шаблон можно подключить и сторонний код, например, из библиотеки bootstrap. А дальше всё зависит от фантазии и чувства вкуса.

На сегодня всё.

среда, 22 августа 2018 г.

A programmer: JavaScript #1.

Мои метания вокруг программирования привели меня к JavaScript'у. На самом деле это несколько странно, учитывая, что ещё полгода-год назад я учился программировать для Android с тем, чтобы написать несколько набольших полезных программ и выложить в Play Store (он же Play Market). Я видел в этом то преимущество, что эти программы были бы свидетельством моего умения, во-первых, и, возможно, по мере их (программ) развития, приносили бы какую-нибудь копеечку, во-вторых. Собственно, я планирую к этому ещё вернуться.


Но JavaScript для меня оказался привлекательным рядом дополнительных плюсов:

  • Под Android из моих друзей никто не программирует, а значит, спросить совета у живого человека было бы затруднительно. В свою очередь, на курсах по Java, на которые я ходил 2 года назад, я познакомился с Лёшей (фамилию уточнять не буду, ибо не уполномочен), который оказался замечательным ментором. А он некоторое время назад как раз получил работу как JavaScript-программист. Значит, в крайнем случае мне есть с кем проконсультироваться.
  • Как я знаю, JavaScript является весьма востребованным языком программирования, и порог вхождения в него существенно ниже, чем для Java. С некоторых пор я существенно более, чем раньше, заинтересован в том, чтобы найти работу в IT.
  • JavaScript заточен под Web-разработку, а мне ещё в детстве нравилось то, что теперь наывается версткой (стенгазеты - наше всё:)).

Вот, собственно, поэтому я решил попробовать себя здесь.

Лёша предложил мне попробовать сделать приблизительно такое же тестовое задание, которое обычно дают при приёме на работу:

  • поднять сервер NodeJS;
  • сделать к нему фронт на каких-нибудь шаблонах (например, на ejs);
  • подключить базу данных (MongoDB или PostgreSQL);
  • сделать в БД пару таблиц со связями;
  • сделать к ним CRUD;
  • вывести их на фронт;
  • дополнительно - какой-нибудь функционал для работы с таблицами;
  • дополнительно - аутентификацию.

Собственно, этим я и занимаюсь уже второй месяц - пока, к сожалению, не так интенсивно, как хотелось бы. Зачем я вдруг решил поделиться этим с "миром"? Затем, что мне нужен конспект, а писать его только самому себе - скучно. Плюс Ричард Фейнман справедливо полагал, что лучший способ что-то понять и выучить - это рассказать об этом другим. Это же я имел в виду, например, когда выкладывал свои учебные результаты по Java. Теперь собираюсь быть более последовательным, чем тогда.

***
Для чего нужен и в чём особенность JavaScript'a? Если коротко, то JavaScript изначально заточен на то, чтобы сделать вебстраницы интерактивными. Хотя впоследствии на нём стали писать и серверную часть, и всё остальное, главное в нём именно это - поэтому он и входит третьим элементом в стэк веб-технологий:


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


NodeJS - это программная платформа для JavaScript'а, то есть то, что и позволяет работать JavaScript'у, в том числе и в первую очередь в качестве языка для веб-сервера. Так, чтобы создать веб-сервер нужен следующий код (скан из Википедии):



Зачем нужен сервер? Вопрос вроде бы странный, но у меня он почему-то возник на горизонте сознания, поэтому стоит ответить на него. Если вспомнить, что веб-приложения выполняют некоторый код (то есть, в сущности, производят вычисления), то возникает вопрос, где - грубо говоря, на каком оборудовании - эти вычисления происходят? Это может быть либо компьютер пользователя ("клиент"), либо удаленный компьютер, специально предназначенный для этого ("сервер"). Другими словами, всё то, что происходит не на компьютере пользователя (в случае веб-приложений - в браузере), происходит на сервере. Но для этого там должно быть установлено сообветствующее программное обеспечение (в нашем случае - NodeJS), которое и взаимодействует с "железом". Вот мы на основе этого программного обеспечения создаем свой веб-сервер. Мой вариант выглядит вот так:


Как видно, он практически такой же, как предыдущий, только сервер другой (оба - локальные, а не удалённые, у нас пока удалённых нету) и выводится другое. А именно: вместо "некоторый html" можно подставить этот самый html, отображающий что-то в окне браузера, хотя чаще там находится ссылка на находящуюся в другом месте страницу (обычно свёрстанную с использованием шаблонов, которые ещё где-то отдельно находятся).

Пока что запуск нашего файла выводит в консоль заданный текст. А что вообще делает наш сервер? Он "слушает", что делает пользователь. То есть он воспринимает его действия на переданной ему нами странице (в нашем случае это http://127.0.0.1:3000/) и должен как-то реагировать на эти действия. Собственно, наша задача и состоит в том, чтобы сервер на определенные действия (запросы) реагировал определенным образом.

Какие это могут быть действия? Обычно в случае простого веб-приложения или сайта их набор довольно небольшой, например: "показать такую-то страницу" - с информацией о том или об этом. То есть, если действие такое, показываем одно, если другое, то другое, если действие не предусмотрено нами, то показываем сообщение об ошибке, например. Но что такое "действие" в нашем случае?

Самый простой вариант - пользователь что-то ввёл в строке браузера после http://127.0.0.1:3000/ (то есть, находясь на том сервере, который мы "слушаем"). Например, он набрал "http://127.0.0.1:3000/about", желая получить информацию, допустим, о сайте (ну или чаще - нажал кнопку, соответствующую этому действию). Такое действие называется GET-запрос - это когда передаваемый пользователем запрос достаточно простой и может передаваться через строку браузера. Если мы хотим, чтобы наше приложение в ответ на этот запрос что-то сделало, мы, соответственно, должны это запрограммировать. Например так:


Здесь: если пользователь ничего не делал, показываем ему файл "index", если набрал "about", показываем ему файл "about" (оба файла лежат в другом месте).

Главный нюанс состоит в следующем - чтобы всё, что мы написали, работало, мы должны использовать объект app (на котором вызываем функцию get), а чтобы его использовать, мы должны подключить модуль "express" - одну из библиотек, работа с которыми (а не только с синтаксисом) и является, пожалуй, сутью программирования на том или ином языке. NodeJS как раз и хорош тем, что позволяет легко подключать разные модули - как чужие, так и написанные самостоятельно.

Разумеется, соответствующие файлы должны находиться в папке проекта. Для того, чтобы удобно закачивать себе всё, что нужно, NodeJS имеет собственный пакетный менеджер (npm - node packages manager), хотя есть и сторонние разработки (например, yarn). С его помощью легко инсталлировать нужные модули себе в проект.

И тут появляется нюанс. Часть модулей нужны для функционирования приложения, а часть - только для его разработки (например, проверка синтаксиса или стиля кода). Если над проектом работают больше одного человека, последние модули могут быть не нужны кому-то другому (а место занимать), значит, надо как-то обозначить, чтобы при клонировании проекта они не загружались автоматически. Это, как и другие вещи, описываются в файле package.json.

Собственно, когда мы инициализируем новый проект в IDE (я использую Atom), нам как раз и предлагается определить некую базовую информацию, которая будет записана в package.json. Выглядит он приблизительно так:


Здесь среди прочего (имя, версия, описание, автор, лицензия, стартовый файл и т.д.) указаны зависимости (внешние пакеты - "depenencies", с указанием их версий), которые надо подгружать в наш проект автоматически, зависимости, использующиеся для разработки, о которых мы говорили ("devDependencies"), скрипты, выполняемые при старте, и т.д.

***

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