%Teilweise Erzeugt mit dem LaTeX-Generator: http://latex.sehnot.de

%Schriftgröße, Layout, Papierformat, Art des Dokumentes
\documentclass[10pt,oneside,a4paper]{scrartcl}

%Einstellungen der Seitenränder
\usepackage[left=2cm,right=2cm,top=1.5cm,bottom=1.5cm,includeheadfoot]{geometry}

%neue Rechtschreibung
\usepackage[ngerman]{babel}

%Umlaute ermöglichen
\usepackage[utf8]{inputenc}

%Gesamtseitenzahl
\usepackage{lastpage}

% Kopf- und Fußzeile
\usepackage[automark]{scrpage2}

%Quellcode-Listings
\usepackage{listings}

%Hyperlinks
\usepackage{hyperref}

% Rahmen um Verbatim
\usepackage{fancyvrb}
\usepackage{moreverb}

% correct single quotes
\usepackage{upquote,textcomp}



%Kopfzeile
\ihead{Webentwicklung}
\chead{}
\ohead{http://kohnlehome.de/html/node-rest.pdf}
\setheadsepline{0.5pt}

%Fußzeile
\setfootsepline{0.5pt}
\ifoot{Franz Kohnle}
\cfoot{Seite \thepage\ von  \pageref{LastPage}}
\ofoot{\today}

\pagestyle{scrheadings}

\begin{document}

% Überschrift 
\begin{center}
\LARGE % Schriftgröße
\bfseries % Fettdruck
\sffamily % Serifenlose Schrift
REST-API mit Node, Express und MongoDB
\end{center}



\section{Installation von Node.js, MongoDB}
\subsection*{Download}
\href{https://nodejs.org/}{nodejs.org}, \href{https://www.mongodb.com/download-center/community}{mongodb.com}

\subsection*{Test}
\begin{tabular}{l l}
\texttt{\$ node -v} & v10.15.0\\
\texttt{\$ npm -v} &  6.4.1\\
\texttt{\$ mongo --version} &  MongoDB shell version v4.0.5 (evtl. PATH setzten)
\end{tabular}

\section{Projekt erstellen}
\begin{tabular}{l l}
\texttt{\$ npm init} & erstellt im aktuellen Verzeichnis die Datei \textit{package.json}
\end{tabular}

\section{Hallo Welt in Konsole}
\subsection*{index.js}
\begin{boxedverbatim}
console.log('Hallo Welt!');
\end{boxedverbatim}

\subsection*{Script starten}
\begin{tabular}{l l}
\texttt{\$ node index} & 
\end{tabular}

\section{Webserver nur mit Node}
\subsection*{index.js}
\begin{boxedverbatim}
const http = require('http');

http.createServer(function(request, response) {
   response.writeHead(200, {'Content-Type': 'text/plain'});
   response.end('Hallo Welt!');
}).listen(3000);

console.log('Server läuft auf Port 3000');
\end{boxedverbatim}

\subsection*{Script starten}
\begin{tabular}{l l}
\texttt{\$ node index.js} & 
\end{tabular}

\subsection*{Mit Browser auf Webserver zugreifen}
\begin{tabular}{l l}
\texttt{http:\textbackslash\textbackslash localhost:3000 } & 
\end{tabular}

\newpage

\section{Webanwendung mit express}
\subsection*{express installieren}
\begin{tabular}{l l}
\texttt{\$ npm install express --save} & Installation im aktuellen Verzeichnis, Dependency in package.json
\end{tabular}

\subsection*{index.js}
\begin{boxedverbatim}
const express = require('express');
const app = express();

app.get('/', function(req, res) {
  res.send('Hallo Welt!');
});

app.listen(3000, function() {
  console.log('Server läuft auf Port 3000');
});
\end{boxedverbatim}



\section{API-Routes}
\subsection*{api-routes.js}
\begin{boxedverbatim}
const router = require('express').Router();

router.get('/', function (req, res) {
    res.json({
       status: 'API funktioniert',
       message: 'Willkommen zur REST-API!'
    });
});

module.exports = router;
\end{boxedverbatim}

\subsection*{zu index.js hinzufügen:}
\begin{boxedverbatim}
const apiRoutes = require('./api-routes');
app.use('/api', apiRoutes);
\end{boxedverbatim}

\subsection*{Zugriff}
\begin{tabular}{l l}
\texttt{http:\textbackslash\textbackslash localhost:3000 } & Hallo Welt!\\
\texttt{http:\textbackslash\textbackslash localhost:3000\textbackslash api } & \{'status': 'API funktioniert', 'message': 'Willkommen zur REST-API!'\}
\end{tabular}

\newpage

\section{MongoDB}
\subsection*{MongoDB starten}
\begin{tabular}{l l}
\texttt{\$ mongod} & 
\end{tabular}

\subsection*{mongoose und body-parser installieren}
\begin{tabular}{l l}
\texttt{\$ npm install mongoose --save} & MongoDB object modeling\\
\texttt{\$ npm install body-parser --save} & Parse incoming request bodies
\end{tabular}

\subsection*{index.js}
\small
\begin{boxedverbatim}
const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const apiRoutes = require('./api-routes');

const app = express();

app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(bodyParser.json());

mongoose.connect('mongodb://localhost/mongorest', { useNewUrlParser: true });
let db = mongoose.connection;

app.get('/', function(req, res) {
    res.send('Hallo Welt!');    
});

app.use('/api', apiRoutes);

app.listen(3000, function() {
    console.log('Server läuft auf Port 3000');
});
\end{boxedverbatim}

\section{Controller und Model}
\subsection*{model.js}
\small
\begin{boxedverbatim}
const mongoose = require('mongoose');

const contactSchema = mongoose.Schema({
    name: {
        type: String,
        required: true
    },        
    email: {
        type: String,
        required: true
    },
    gender: String,
    phone: String,
    create_date: {
        type: Date,
        default: Date.now
    }
});

const Contact = module.exports = mongoose.model('contact', contactSchema);

module.exports.get = function (callback, limit) {
    Contact.find(callback).limit(limit);
}
\end{boxedverbatim}


\subsection*{controller.js}
\small
\begin{boxedverbatim}
Contact = require('./model');

// READ
exports.index = function (req, res) {
    Contact.get(function (err, contacts) {
        if (err) {
            res.json({ status: "error",  message: err });
        }else{
            res.json({
                status: "success",
                message: "Contacts retrieved successfully",
                data: contacts 
            });
        }
    });
};

// READ
exports.view = function (req, res) {
    Contact.findById(req.params.contact_id, function (err, contact) {
        if (err){
            res.send(err);
        }else{
            res.json({ message: 'Contact details loading..', data: contact });
        }
    });
};
\end{boxedverbatim}
\newpage
\begin{boxedverbatim}
// CREATE
exports.new = function (req, res) {
    var contact = new Contact();
    contact.name = req.body.name; // ? req.body.name : contact.name;
    contact.gender = req.body.gender;
    contact.email = req.body.email;
    contact.phone = req.body.phone;
    contact.save(function (err) {        
        if(err){
            res.json(err);
        }else{
            res.json({ message: 'New contact created!', data: contact });
        }
    });
};

// UPDATE
exports.update = function (req, res) {
    Contact.findById(req.params.contact_id, function (err, contact) {
        if (err){
            res.send(err);
        }else{
            contact.name = req.body.name ? req.body.name : contact.name;
            contact.gender = req.body.gender;
            contact.email = req.body.email;
            contact.phone = req.body.phone;
            contact.save(function (err) {
                if (err){
                    res.json(err);
                }else{
                    res.json({ message: 'Contact Info updated', data: contact });
                }
            });
        }
    });
};

// DELETE
exports.delete = function (req, res) {
    Contact.remove({_id: req.params.contact_id}, function (err, contact) {
        if (err){
            res.send(err);
        }else{
            res.json({ status: 'success', message: 'Contact deleted' });
        }
    });
};
\end{boxedverbatim}

\subsection*{api-routes.js}
\small
\begin{boxedverbatim}
const router = require('express').Router();

router.get('/', function (req, res) {
    res.json({
        status: 'API is ok',
        message: 'Welcome to REST-API!',
    });
});

const controller = require('./controller');

router.route('/contacts')
    .get(controller.index)
    .post(controller.new);

router.route('/contacts/:contact_id')
    .get(controller.view)
    .patch(controller.update)
    .put(controller.update)
    .delete(controller.delete);

module.exports = router;
\end{boxedverbatim}

\section*{API-Endpunkte}
\begin{itemize}
\item CREATE: POST /api/contacts
\item READ: GET /api/contacts
\item READ: GET /api/contacts/\{id\}
\item UPDATE: PUT /api/contacts/\{id\}
\item DELETE: DELETE /api/contacts/\{id\}
\end{itemize}
\section*{Quellen}
\begin{itemize}
\item \href{https://medium.com/@dinyangetoh/how-to-build-simple-restful-api-with-nodejs-expressjs-and-mongodb-99348012925d}{How To Build Simple RESTful API With NodeJs, ExpressJs And MongoDb}
\end{itemize}
\end{document}
