DEV Community

Cover image for Fullstacking: Restructuring the project
Mark Kop
Mark Kop

Posted on

Fullstacking: Restructuring the project

Ok, so I've gone to @fotontech to get some help to set up Relay and over so many new concepts, new files and new tools I had to refactor our project's structure.
So we're basically restarting with everything we've learned so far
, and we'll be using the project's structure similar to Entria Fullstack.
Our project will have a main package and other sub-packages like our react-native app and server.

Restarting

Within another folder, run the following commands:

npm init // creates new package
git init // initiate git local repository
git add . // stage all folders and files to be commited
git commit -m "main package created" // commits staged files
git remote add origin <url> // links it with remote repository
git push -u origin master // pushes commits setting upstream from master to origin
// you may use -f flag to force push to the older remote repository 
Enter fullscreen mode Exit fullscreen mode

React Native

mkdir packages // creates folder packages
cd packages // move to packages folder
react-native init app // creates a new react-native project
// you can also 'expo init app' to set up a react-native project with expo
cd app
yarn start // starts app
// On another terminal, but the same folder:
react-native run-android // builds the app into your connected smartphone
Enter fullscreen mode Exit fullscreen mode

You might want to check this guide to set up android stuff

You might also configure the following scripts:

// package.json
  "scripts": {
    "start:app": "yarn --cwd packages/app start",
    "android": "yarn --cwd packages/app/android android",
    "shake": "adb shell input keyevent 82", // shakes phone
    "test": "jest"
  }
Enter fullscreen mode Exit fullscreen mode
// packages/app/package.json
  "scripts": {
    "start": "react-native start",
    "android": "react-native run-android",
    "test": "jest",
    "lint": "eslint ."
  }
Enter fullscreen mode Exit fullscreen mode

NodeJS + KoaJS

mkdir server // in packages folder
cd server
npm init // creates a new package
yarn add koa mongoose // adds koa and mongoose dependencies
sudo service mongod start // starts mongodb service
Enter fullscreen mode Exit fullscreen mode
// packages/server.js
const Koa = require("koa");
const mongoose = require("mongoose");

const databaseUrl = "mongodb://127.0.0.1:27017/test";
mongoose.connect(databaseUrl, { useNewUrlParser: true });
mongoose.connection.once("open", () => {
  console.log(`Connected to database: ${databaseUrl}`);
});

const app = new Koa();
app.use(async ctx => {
  ctx.body = "Hello World";
});
app.listen(3000, () =>
  console.log("Server is running on http://localhost:3000/")
);
Enter fullscreen mode Exit fullscreen mode

Run node server.js to test it
Don't forget to sudo service mongod start.
We shall add "start": "nodemon server.js" in the scripts object in this package.json
And "start:server": "yarn --cwd packages/server start" in our root packages.json like we just did with start:app

Mongoose

Now we're going to connect everything and display our database's object (a stapler) in the frontend.

Create the model file again

// packages/server/models/Product.js
var mongoose = require('mongoose');

const ProductSchema = new mongoose.Schema({
  title: String,
});

module.exports = mongoose.model('Product', ProductSchema);
Enter fullscreen mode Exit fullscreen mode

Add query to the server.js file

// packages/server/server.js
const Koa = require("koa");
const mongoose = require("mongoose");
const Product = require("./models/Product");

const databaseUrl = "mongodb://127.0.0.1:27017/test";
mongoose.connect(databaseUrl, { useNewUrlParser: true });
mongoose.connection.once("open", () => {
  console.log(`Connected to database: ${databaseUrl}`);
});

const app = new Koa();

const query = () => {
  return new Promise((resolve, reject) => {
    Product.find({}, (err, res) => {
      if (err) {
        reject(err);
      }
      resolve(res);
    });
  });
};

app.use(async ctx => {
  const data = await query();
  ctx.body = data;
});
app.listen(3000, () =>
  console.log("Server is running on http://localhost:3000/")
);
Enter fullscreen mode Exit fullscreen mode

And finally yarn add axios and add a GET hook in App.js file

// packages/app/App.js
import React, {Fragment, useState, useEffect} from 'react';
import axios from 'axios';
import {Text} from 'react-native';

const App = () => {
  const [title, setTitle] = useState('Loading...');
  useEffect(() => {
    const fetchData = async () => {
      const result = await axios('http://localhost:3000');
      setTitle(result.data[0].title);
    };
    fetchData();
  }, []);

  return (
    <Fragment>
      <Text>Hello World! Product: {title} </Text>
    </Fragment>
  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

Now with yarn start:server and yarn start:app we should be able to see our stapler title "Stampler" on our smartphone's screen.
And I've just realized that I've misspelled stapler this entire time.

Our repository should be looking like this version:
Fullstacking - GitHub - #9724f4cb35

We're now ready to start adding Relay and GraphQL into our app.
Since we were growing in complexity, it was important to organize our project to optimize our time.

References:
Koa, express, node simplified version connected to MongoDB
How to fetch data with React Hooks?
Entria - Monorepo Playground with GraphQL, React, React Native, Relay Modern, TypeScript and Jest

Oldest comments (0)