Jump to content

Simple CRUD api using Mongoose (MongoDb atlas)


LiMi
 Share

Recommended Posts

I want to share my solution to build a simple CRUD api using the NodeJs package mongoose and my MongoDb atlas database. Here is the code i ended up with:

Lolo runs on the Nodejs version 10 at the moment (this has changed to 12 now) so the mongoose version used was 5 in this app and added to the modules section in the app settings.

First node (CRUD): Composite function with 4 Lolo HTTP Triggers with the methods post (create), get (read), put (update) and delete (delete) with fitting paths and names. Ports added with the CRUD names for the composite function and connected with the corresponding HTTP Trigger method to be able to reach in the rest of the app.

Second node (MongoDb connection): To establish a connection to the MongoDb database:

const mongoose = require('mongoose');

exports.setup = async() => {
  async function mongodbConnection() {
    await mongoose.connect(
      "CONNECTION STRING HERE",
      {useNewUrlParser: true, autoReconnect: true },
      () => console.log('connected succesfully to Mongodb')
    );
  };
  mongodbConnection().catch(err => console.error('problem connecting to Mongodb', err));
}

exports.handler = async(ev, ctx) => {
  const { route } = ctx;
  route(ev);
};

Third node (Schema): To create a mongoose schema used for validation and which output port to use based on the HTTP Trigger method:

const mongoose = require('mongoose');

exports.handler = async(ev, ctx) => {
  const { route , log, outputs } = ctx;
  const defString = `default post`;

  const monSchema = new mongoose.Schema({
    title: {
      type: String,
      default: defString
    },
    date: { 
      type: Date, 
      default: Date.now 
      }
  });
  ev.mongooseschema = monSchema;

  //ports
  let port;
  switch(ev.method) {
    case 'GET':
      port = outputs.outR;
      break;
    case 'POST':
      port = outputs.outC;
      break;
    case 'PUT':
      port = outputs.outU;
      break;
    case 'DELETE':
      port = outputs.outD;
      break;
    default:
      log.error('No port choosen');
  }
  route(ev, port);
};

Fourth node (Create): To be able to preform a post towards the database: 

const mongoose = require('mongoose');

exports.handler = async(ev, ctx) => {
    const { emit, log } = ctx;
    const { mongooseschema } = ev;
    const mongoSchema = mongoose.models.posts || mongoose.model('posts', mongooseschema);

    async function postToDb() {
        let body;
        const toPost = new mongoSchema({
            title: ev.body.title
        });
        try {
            await toPost.save();
                body = 'Saved and posted';
        }catch (err){
            log.error('Error posting', err);
            body = 'Something went wrong posting';
        }  
        emit('response', { statusCode: '200', body }); 
    }
    postToDb();
};

Fifth node (Read): To get all or one document by id: 

const mongoose = require('mongoose');

exports.handler = async(ev, ctx) => {
  const { emit, log } = ctx;
  const { mongooseschema } = ev;
  const mongoSchema = mongoose.models.posts || mongoose.model('posts', mongooseschema);
  let getId = ev.body._id;

  if(!getId){
    async function getData() {
      try{
        await mongoSchema
          .find()
          .exec()
          .then(data => {
            const body = data;
            emit('response', { statusCode: '200', body });
          });
      }catch (err) {
        log.error('error preforming get', err);
      }
    }
    getData();
  }else{
    async function getById() {
      try{
        await mongoSchema
          .findById(getId)
          .exec()
          .then(data => {
            const body = data;
            emit('response', { statusCode: '200', body });
          });
      }catch (err) {
        log.error('error preforming get by id', err);
      }
    }
    getById();
  }
};

Sixth node (Update): To update a document of a certain id: 

const mongoose = require('mongoose');

exports.handler = async(ev, ctx) => {
  const { log, emit } = ctx;
  const { mongooseschema } = ev;
  const mongoSchema = mongoose.models.posts || mongoose.model('posts', mongooseschema);
    
  async function updateOneDoc() {
    let body;
    const idToUpdate = { _id: ev.body._id };
    try{
      body = 'Post updated'
      await mongoSchema.findOneAndUpdate(
        idToUpdate,
        { 
          title: ev.body.title
        });
    }catch (err) {
      log.error(`Error updating id: ${idToUpdate}.`, err);
      body = 'Problem updating'    
    }
    emit('response', { statusCode: '200', body }); 
  }
  updateOneDoc();
};

Seventh node (Delete): To delete a certain document of an id or many by title: 

const mongoose = require('mongoose');

exports.handler = async(ev, ctx) => {
  const { emit, log } = ctx;
  const { mongooseschema } = ev;
  const mongoSchema = mongoose.models.posts || mongoose.model('posts', mongooseschema);
  let deleteId = ev.body._id;

  if(!deleteId){
    async function deleteByTitle() {
      let deleteTitle = ev.body.title;
      let body;
      try{
        body = 'Post/Posts deleted'
        await mongoSchema.deleteMany({
        title: deleteTitle
        });
      }catch (err) {
        log.error(`Error deleting title: ${deleteTitle}.`, err);
        body = 'Problem deleting'    
      }
      emit('response', { statusCode: '200', body }); 
    }
    deleteByTitle();
  }else{
    async function deleteById() {
      let body;
      try{
        body = 'Post deleted'
        await mongoSchema.deleteOne({
        _id: deleteId
        });
      }catch (err) {
        log.error(`Error deleting id: ${deleteId}.`, err);
        body = 'Problem deleting'    
      }
      emit('response', { statusCode: '200', body }); 
  }
    deleteById();
  }
};

In the attached image you can see how all the nodes are connected.

E2001001-765A-496B-86E3-FE96BAEAF3D6.jpeg

Link to comment
Share on other sites

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...