DEV Community

Jesus Gilbert
Jesus Gilbert

Posted on • Edited on

30 6

Build a simple blog with GraphQL, Node.js, SQLite and (VUE, Angular Or ReactJS)

What gonna we do?

In this tutorial, we will show you how to create a simple and powerful Blog with (VUE, Angular and React), GraphQL, Node.js and SQLite.

We will divide this tutorial as follows:

  • Part 1: Build a web api with GraphQL, Node.js and SQLite.
  • Part 2: Build a Client in VUE.
  • Part 3: Build a Client in Angular.
  • Part 4: Build a Client in ReactJS.

Prerequisites

  • Node.js and JavaScript knowledge
  • NPM Command
  • knowledge of VUE,Angular or ReactJS

What is GraphQL?

According to https://graphql.org/learn: GraphQL is a query language for your API, and a server-side runtime for executing queries by using a type system you define for your data. GraphQL isn't tied to any specific database or storage engine and is instead backed by your existing code and data

Well let's start the game

  • Set up the project, run this on your favorite terminal:
    • mkdir micro-blog
    • mkdir micro-blog-api
    • cd micro-blog-api
    • npm init -y
  • Install the following dependencies:
    • npm install graphql express --save
    • npm install express-graphql --save
    • npm install sqlite3 --save
  • Create an index.js in the root to configurate GraphQL.
  • Paste this code on index.js:
    const express = require('express');
    const ExpressGraphQL = require("express-graphql");
    const schema = require("./graphql/post/post.js");
    const app = express();
    app.use("/graphql", ExpressGraphQL({ schema: schema.schema, graphiql: true}));
    app.listen(4000, () => {
    console.log("GraphQL server running at http://localhost:4000.");
    });
    view raw gistfile1.js hosted with ❤ by GitHub
  • Create a graphql folder and then create a post folder inside -Create a post.js inside of post folder.
  • Paste this code on post.js
    const graphql = require("graphql");
    const sqlite3 = require('sqlite3').verbose();
    //create a database if no exists
    const database = new sqlite3.Database("../micro-blog.db");
    //create a table to insert post
    const createPostTable = () => {
    const query = `
    CREATE TABLE IF NOT EXISTS posts (
    id integer PRIMARY KEY,
    title text,
    description text,
    createDate text,
    author text )`;
    return database.run(query);
    }
    //call function to init the post table
    createPostTable();
    //creacte graphql post object
    const PostType = new graphql.GraphQLObjectType({
    name: "Post",
    fields: {
    id: { type: graphql.GraphQLID },
    title: { type: graphql.GraphQLString },
    description: { type: graphql.GraphQLString },
    createDate: { type: graphql.GraphQLString },
    author: { type: graphql.GraphQLString }
    }
    });
    // create a graphql query to select all and by id
    var queryType = new graphql.GraphQLObjectType({
    name: 'Query',
    fields: {
    //first query to select all
    Posts: {
    type: graphql.GraphQLList(PostType),
    resolve: (root, args, context, info) => {
    return new Promise((resolve, reject) => {
    // raw SQLite query to select from table
    database.all("SELECT * FROM Posts;", function(err, rows) {
    if(err){
    reject([]);
    }
    resolve(rows);
    });
    });
    }
    },
    //second query to select by id
    Post:{
    type: PostType,
    args:{
    id:{
    type: new graphql.GraphQLNonNull(graphql.GraphQLID)
    }
    },
    resolve: (root, {id}, context, info) => {
    return new Promise((resolve, reject) => {
    database.all("SELECT * FROM Posts WHERE id = (?);",[id], function(err, rows) {
    if(err){
    reject(null);
    }
    resolve(rows[0]);
    });
    });
    }
    }
    }
    });
    //mutation type is a type of object to modify data (INSERT,DELETE,UPDATE)
    var mutationType = new graphql.GraphQLObjectType({
    name: 'Mutation',
    fields: {
    //mutation for creacte
    createPost: {
    //type of object to return after create in SQLite
    type: PostType,
    //argument of mutation creactePost to get from request
    args: {
    title: {
    type: new graphql.GraphQLNonNull(graphql.GraphQLString)
    },
    description:{
    type: new graphql.GraphQLNonNull(graphql.GraphQLString)
    },
    createDate:{
    type: new graphql.GraphQLNonNull(graphql.GraphQLString)
    },
    author:{
    type: new graphql.GraphQLNonNull(graphql.GraphQLString)
    }
    },
    resolve: (root, {title, description, createDate, author}) => {
    return new Promise((resolve, reject) => {
    //raw SQLite to insert a new post in post table
    database.run('INSERT INTO Posts (title, description, createDate, author) VALUES (?,?,?,?);', [title, description, createDate, author], (err) => {
    if(err) {
    reject(null);
    }
    database.get("SELECT last_insert_rowid() as id", (err, row) => {
    resolve({
    id: row["id"],
    title: title,
    description: description,
    createDate:createDate,
    author: author
    });
    });
    });
    })
    }
    },
    //mutation for update
    updatePost: {
    //type of object to return afater update in SQLite
    type: graphql.GraphQLString,
    //argument of mutation creactePost to get from request
    args:{
    id:{
    type: new graphql.GraphQLNonNull(graphql.GraphQLID)
    },
    title: {
    type: new graphql.GraphQLNonNull(graphql.GraphQLString)
    },
    description:{
    type: new graphql.GraphQLNonNull(graphql.GraphQLString)
    },
    createDate:{
    type: new graphql.GraphQLNonNull(graphql.GraphQLString)
    },
    author:{
    type: new graphql.GraphQLNonNull(graphql.GraphQLString)
    }
    },
    resolve: (root, {id, title, description, createDate, author}) => {
    return new Promise((resolve, reject) => {
    //raw SQLite to update a post in post table
    database.run('UPDATE Posts SET title = (?), description = (?), createDate = (?), author = (?) WHERE id = (?);', [title, description, createDate, author, id], (err) => {
    if(err) {
    reject(err);
    }
    resolve(`Post #${id} updated`);
    });
    })
    }
    },
    //mutation for update
    deletePost: {
    //type of object resturn after delete in SQLite
    type: graphql.GraphQLString,
    args:{
    id:{
    type: new graphql.GraphQLNonNull(graphql.GraphQLID)
    }
    },
    resolve: (root, {id}) => {
    return new Promise((resolve, reject) => {
    //raw query to delete from post table by id
    database.run('DELETE from Posts WHERE id =(?);', [id], (err) => {
    if(err) {
    reject(err);
    }
    resolve(`Post #${id} deleted`);
    });
    })
    }
    }
    }
    });
    //define schema with post object, queries, and mustation
    const schema = new graphql.GraphQLSchema({
    query: queryType,
    mutation: mutationType
    });
    //export schema to use on index.js
    module.exports = {
    schema
    }
    view raw post.js hosted with ❤ by GitHub
  • Update the package.json file to add de following script to start the api server
    • "start": "node index.js"
  • Then on console or terminal run de server:
    • npm run start
  • Then if all is correct open your browser and go to localhost:4000/graphql and you gonna see your graphql server run: Alt Text
  • If you want select all post run this
    query{
    Posts{
    id,
    title,
    description,
    createDate,
    author
    }
    }
    view raw js hosted with ❤ by GitHub
  • If you want to create
    mutation {
    createPost(title: "Mi primer Post", description: "en mi primer post tengo que la vida no es facil", createDate:"25-09-2019",author:"Jesus GIlbert") {
    id,
    title,
    description,
    createDate,
    author
    }
    }
    view raw js hosted with ❤ by GitHub
  • If you want to update
    mutation {
    updatePost(
    id:2,
    title: "Mi segundo Post",
    description: "en mi primer post tengo que la vida no es facil",
    createDate:"26-09-2019",
    author:"Jesus GIlbert"
    )
    }
    view raw js hosted with ❤ by GitHub
  • If you want to delete
    mutation {
    deletePost(id:1)
    }
    view raw js hosted with ❤ by GitHub

This is all, if you want to clone this project go to github: https://github.com/jgilbertcastro/micro-blog

In the part 2 i'm gonna show you how to build a client for consume this API.

Top comments (2)

Collapse
 
plurbi profile image

Can you make It with angular, using ngrx?

Collapse
 
jgilbertcastro profile image
Jesus Gilbert

First I will make it with Vue and then with angular. I will notify you