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:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
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."); }); - 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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
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 } - 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:
- If you want select all post run this
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
query{ Posts{ id, title, description, createDate, author } } - If you want to create
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
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 } } - If you want to update
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
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" ) } - If you want to delete
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
mutation { deletePost(id:1) }
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)
Can you make It with angular, using ngrx?
First I will make it with Vue and then with angular. I will notify you