We were looking for a simple tutorial to follow for our weekly meetings and picked one last minute. It ended up being very outdated, so I've created this as an update and also an expansion to that original tutorial.
We assume you have a web browser, node, npm, and git installed as well as a bash shell. We also hope you have some sort of api testing tool installed like Postman, Insomnia, or httpie.
If you already completed this part you can skip to Part 2
Create a project folder and basic setup by doing the following:
mkdir myblog
cd myblog
npm init -y
Now is the best time to initialize git! Pay attention to the status between every other git command.
git init
git status
git add .
git status
git commit -m "init commit"
git status
- You should now see
package.json
as a file in your folder.
We'll make 2 new files:
touch index.js
touch .env
Now you'll install some npm modules that you'll need for this app:
npm i express cors dotenv
npm i -D nodemon
express is a framework for building API's and web applications
cors handles cross origin requests
More documentation on these is available at Expressjs.com
dotenv loads the .env
into system variables - used to keep them secret
nodemon restarts the server when it detects changes in our code files so we don't have to.
- The
-D
in this command saves this as a dev dependency - it won't be used when the server is eventually deployed
Open the .env
file and add the following:
PORT=8080
Now we'll build index.js
into a basic express server
// index.js
require('dotenv').config()
const express = require('express')
const server = express()
server.get('/hello', (req, res) => {
res.json({ message: 'Hello from the Server' })
})
server.listen(process.env.PORT, () => console.log(`Listening on port ${process.env.PORT}!`))
Replace scripts in package.json
to easily run your server
// package.json
...
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js"
}
...
Type in npm run dev
in your terminal - if there are no errors it's working!
In your browser - go to localhost:8080/hello
, you should see something like this:
We'll take the help of using a preconfigured .gitignore
file so we don't commit thousands of files and our secrets to our repo.
npx gitignore node
NOW it's safe to commit our files
git add .
git commit -m "first working server"
We'll setup eslint to help us know if our code's syntax is broken
To install eslint:
npx eslint --init
Now it will ask us a few questions - for this project, using arrow keys and the space bar, we'll answer them as follows :
How would you like to use ESLint? | To check syntax and find problems |
What type of modules does your project use? | CommonJS (require/exports) |
Which framework does your project use? | None of these |
Does your project use TypeScript? | No |
Where does your code run? | node only |
What format do you want your config file to be in? | JSON |
Would you like to install them now with npm? | Yes |
This should have created a file called .eslintrc.json
with the following contents:
// .eslint.json
{
"env": {
"commonjs": true,
"es2021": true,
"node": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 12
},
"rules": {}
}
It should have also added an eslint
entry in your package.json
under devDependencies
Every time we complete a step is a good time to commit
git add .
git commit -m 'added eslint'
We should try to maintain "separation of concerns" while we build this app. In order to do that we need to determine what those concerns are.
The first step a server needs to do is listen for connections, so we'll make that the sole concern of index.js
and create a separate server.js
file to handle those connections.
mkdir api
touch api/server.js
Now cut everything but the server.listen
line out of index.js
and paste it into server.js
At the top of index.js
add the line
// index.js
const server = require('./api/server')
and at the bottom of server.js
add the line
// /api/server.js
module.exports = server
With that complete, our server should be working again. Test by going to localhost:8080/hello in your browser - or even better Postman - and you should get the welcome message again.
git add .
git commit -m 'separate server into api directory'
Express apps generally follow a pattern - our server.js
file is already checking off a number of the boxes.
// /api/server.js
// Import dependancies
// - brings in all of the modules we'll be using
require('dotenv').config()
const express = require('express')
const cors = require('cors')
// Create an instance of an express app
// - create the actual server object
const server = express()
// Connect the app to global middleware
// - functions that every endpoint passes through
server.use(cors())
server.use(express.json())
// Endpoints check connection and perform functions
// - the code that sends and receives messages and determines what to do
server.get('/hello', (req, res) => {
res.json({ message: 'Hello from the Server' })
})
// Listen to or export server
// - what the rest of the world connects to
module.exports = server
C.R.U.D is an acronym for:
- Create
- Read
- Update
- Delete
Let's make a posts folder in the api directory and posts.router.js
file inside of that
Add some comments
// /api/posts/posts.router.js
// [CREATE] a new post
// [READ] ALL of the posts
// [READ] a single post
// [UPDATE] the data in a post
// [DELETE] a post
These roughly translate to http protocol methods and SQL commands
-------- → - HTTP - → - SQL -
[CREATE] → [POST] → [INSERT]
[READ] → [GET] → [SELECT]
[UPDATE] → [PUT] → [UPDATE]
[DELETE] → [DELETE] → [DELETE]
Our server will eventually communicate with our database using http methods and if our database is SQL based we'll need to know a little about SQL even with an ORM.
ORM stands for "Object-relational mapping" and it is a piece of software that stands between your app and database. Often different databases are used to develop with vs production, an ORM lets you write code once and then it will translate to the specific database's flavor of SQL.
The other thing we need to know a little about is the http protocol. In order to ask for data or send data we need to know where and how that data should be sent.
Since this will be part of our express server, we have to import it by adding const express = require('express')
at the top of our file. Unlike the server, we are creating a endpoints on a route, so we will inform express by typing const router = express.Router()
on the next line.
Now we'll put in some endpoints:
// /api/posts/posts.router.js
const express = require('express')
const router = express.Router()
// [CREATE] a new post
router.post('/', (req, res) => {
res.json({ message: 'Creating a new post' })
})
// [READ] a post
router.get('/:id', (req, res) => {
const id = req.params.id
res.json({ message: `Getting post with id: ${id}` })
})
// [UPDATE] the data in a post
router.put('/:id', (req, res) => {
const id = req.params.id
res.json({ message: `Updated post with id: ${id}` })
})
// [DELETE] a post
router.delete('/:id', (req, res) => {
const id = req.params.id
res.json({ message: `Deleting post with id: ${id}` })
})
// * [READ] ALL of the posts
router.get('/', (req, res) => {
res.json({ message: 'Getting all posts' })
})
module.exports = router
And then import it into our server
// /api/server.js
// Import dependencies
// - brings in all of the modules we'll be using
require('dotenv').config()
const cors = require('cors')
const postsRouter = require('./posts/posts.router')
const express = require('express')
// Create and instance of an express app
// - create the actual server object
const server = express()
// Connect the app to global middleware
// - functions that every endpoint passes through
server.use(cors())
server.use(express.json())
// Endpoints check connection and perform functions
// - the code that sends and receives messages and determines what to do
server.use('/api/posts', postsRouter)
server.get('/hello', (req, res) => {
res.json({ message: 'Hello from the Server' })
})
// Listen to or export server
// - what the rest of the world connects to
module.exports = server
git add .
git commit -m 'Add endpoints'
Go to your repositories on GitHub and click on New Name your repository (I've named mine blog-app-api) and add a description if you'd like. Choose if you want your project to be Public or Private and then create repository.
GitHub Should have popped up some instructions that we'll go ahead and follow:
git remote add origin <Link to your repo>
git branch -M main
git push -u origin main
That should have pushed your code! See you in Part 2