[SOLUTION] Using ObjectId as shortened URL - URL Shortener Microservice

Hi all!
Here I’ve used the ObjectId of the URL stored in MongoDB as the shortened URL. This works fine for me. OPEN FOR REVIEWS.

//DB-SCHEMA
var Schema = mongoose.Schema;
var urlShortnerSchema = new Schema({
  url: String
});
var urlShortner = mongoose.model("urlShortner", urlShortnerSchema);

//Function to extract domain name from URL
//This is because I use dns.resolve()
let urlExtractor = function(url) {
  var urlSplit = url.split("https://");
  if (urlSplit[1] == undefined) {
    return urlSplit[0].split("/")[0];
  } else {
    return urlSplit[1].split("/")[0];
  }
};

//Input
app.post("/api/shorturl/new", function(req, res) {
  var url = req.body.url;
  var extractedUrl = urlExtractor(req.body.url);
  dns.resolveAny(extractedUrl, (err, address) => {
    if (err) {
      console.log(err, address);
      res.json({ error: "invalid URL" });
    } else {
      var urlRecord = new urlShortner({ url: url });
      urlRecord.save((err, data) => {
        if (err) res.json({ error: "invalid URL" });
        else {
          res.json({ original_url: url, short_url: data._id.toString() });
        }
      });
    }
  });
});

//Output-Redirect
app.get("/api/shorturl/:shorturl", function(req, res) {
  let shorturl = req.params.shorturl;
  let urlId;
  try {
    urlId = mongoose.Types.ObjectId(shorturl);
  } catch (err) {
    res.json({ error: "invalid URL" });
    console.log("error" + urlId);
  }
  let completeurl = urlShortner.findById(urlId, (err, data) => {
    if (err) {
      res.json({ error: "invalid URL" });
      console.log("error" + urlId);
    } else {
      res.status(301).redirect(data.url);
      console.log("Success" + urlId);
    }
  });
});

Code link : https://glitch.com/~thinkable-woolly-money
Live App : https://thinkable-woolly-money.glitch.me

5 Likes

Hi! I tried another solution but the FCC tests went wrong, it worked but it didn’t pass so I tried your solution and it was great! I have just one suggestion, at “redirect(data.url)” to write “redirect(`http://${data.url}`)” this way it will redirect to the link. Thanks!

Edit: now I understand, if we use template strings, it doesn’t pass the tests!

1 Like

Thank you @andrekubotsu :innocent:

As you see in the code,

//This is because I use dns.resolve()
let urlExtractor = function(url) {
  var urlSplit = url.split("https://");
  if (urlSplit[1] == undefined) {
    return urlSplit[0].split("/")[0];
  } else {
    return urlSplit[1].split("/")[0];
  }
};

This will work only for https:// sites.

Hey, I have one question,

let urlExtractor = function(url) {
  var urlSplit = url.split("https://");
  if (urlSplit[1] == undefined) {
    return urlSplit[0].split("/")[0];
  } else {
    return urlSplit[1].split("/")[0];
  }
};

why did you split the url second time with ‘/’ , why not just

return urlSplit[0]

or

return urlSplit[1]

since if we split the url https://freeCodeCamp.org , the
urlSplit[0] would be undefined and urlSplit[1] would be freeCodeCamp.org

1 Like

Hii @qaz6209031, Thanks for reaching out…

So my intention behind having the if…else… is, I was assuming that the inputs could be of 2 types,

  1. www.freecodecamp.org”, for which the following would work
if (urlSplit[1] == undefined) {
    return urlSplit[0].split("/")[0];
  }
  1. https://www.freecodecamp.org”, for which the following would work
else {
    return urlSplit[1].split("/")[0];
  }

(Side note: in my current code, this will not work, because the URL which I am storing in DB is wrong (original URL), instead it should have extracted URL)