In this lecture, we are going to be refactoring a reading list Express application.
Currently, that application's model uses an in-memory array to manage a list of books. As a result, the data will only persist as long as the server is up and running. We will refactor this project using Knex to connect to a PostgreSQL database to manage a persistent set of data.
- Create a database called
books
- create
src/db
folder npx knex init
- Configure the
knexfile.js
(remember torequire('path')
)
const path = require('path');
module.exports = {
development: {
client: 'pg',
connection: {
database: 'books',
user: 'benspector',
password: 'postgres'
},
migrations: {
directory: path.join(__dirname, 'src', 'db', 'migrations')
},
seeds: {
directory: path.join(__dirname, 'src', 'db', 'seeds')
}
}
}
npx knex migrate:make create_books_table
exports.up = (knex) => {
return knex.schema.createTable('books', (table) => {
table.increments('id').primary();
table.string('title').notNullable();
table.string('published_year').notNullable();
});
};
exports.down = (knex) => {
return knex.schema.dropTable('books');
};
npx knex migrate:latest
npx knex seed:make seed_books
exports.seed = async function(knex) {
// Deletes ALL existing entries
await knex('books').del()
await knex('books').insert([
{ title: 'Learn to Git With It', published_year: 2015 },
{ title: 'HTML for Dummies', published_year: 2018 },
{ title: 'Advanced JavaScript', published_year: 2009 },
{ title: 'Starting Express', published_year: 2010 },
{ title: 'Node for Noobies', published_year: 2020 }
]);
};
npx knex seed:run
- move
src/models
folder intosrc/db
(update thesrc/middleware/add-books
import) - Test to make sure everything still works!
- create
src/db/models/knex.js
file
const env = 'development';
const config = require('../../../knexfile')[env];
const knex = require('knex')(config);
module.exports = knex;
- Update
src/models/books/
to useknex
- We don't need the
static #all
array anymore! - Replace array manipulation logic with
knex.raw
queries - Remember to use
try/catch
!
- We don't need the
Here is an example:
static async list() {
try {
const result = await knex.raw(`
SELECT *
FROM books;
`);
return result.rows;
} catch (err) {
console.error(err);
return null;
}
}
- Update controller functions to use
async
andawait
. - Instead of using the
Book
constructor, we'll use astatic create
method. - Update
src/controllers/books/create
to use theBook.create
method instead of the constructor.