This service is both guaranteed to be up (they're hosting it) and should allow CORS for all requests (including the tests).
120 lines
3.9 KiB
Markdown
120 lines
3.9 KiB
Markdown
---
|
|
id: bd7158d8c443edefaeb5bd0e
|
|
title: URL Shortener Microservice
|
|
challengeType: 4
|
|
forumTopicId: 301509
|
|
dashedName: url-shortener-microservice
|
|
---
|
|
|
|
# --description--
|
|
|
|
Build a full stack JavaScript app that is functionally similar to this: <https://url-shortener-microservice.freecodecamp.rocks/>. Working on this project will involve you writing your code using one of the following methods:
|
|
|
|
- Clone [this GitHub repo](https://github.com/freeCodeCamp/boilerplate-project-urlshortener/) and complete your project locally.
|
|
- Use [our repl.it starter project](https://repl.it/github/freeCodeCamp/boilerplate-project-urlshortener) to complete your project.
|
|
- Use a site builder of your choice to complete the project. Be sure to incorporate all the files from our GitHub repo.
|
|
|
|
When you are done, make sure a working demo of your project is hosted somewhere public. Then submit the URL to it in the `Solution Link` field. Optionally, also submit a link to your projects source code in the `GitHub Link` field.
|
|
|
|
# --instructions--
|
|
|
|
**HINT:** Do not forget to use a body parsing middleware to handle the POST requests. Also, you can use the function `dns.lookup(host, cb)` from the `dns` core module to verify a submitted URL.
|
|
|
|
# --hints--
|
|
|
|
You should provide your own project, not the example URL.
|
|
|
|
```js
|
|
(getUserInput) => {
|
|
assert(
|
|
!/.*\/url-shortener-microservice\.freecodecamp\.rocks/.test(
|
|
getUserInput('url')
|
|
)
|
|
);
|
|
};
|
|
```
|
|
|
|
You can POST a URL to `/api/shorturl/new` and get a JSON response with `original_url` and `short_url` properties. Here's an example: `{ original_url : 'https://freeCodeCamp.org', short_url : 1}`
|
|
|
|
```js
|
|
async (getUserInput) => {
|
|
const url = getUserInput('url');
|
|
const urlVariable = Date.now();
|
|
const fullUrl = `${url}/?v=${urlVariable}`
|
|
const res = await fetch(url + '/api/shorturl/new/', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
body: `url=${fullUrl}`
|
|
});
|
|
if (res.ok) {
|
|
const { short_url, original_url } = await res.json();
|
|
assert.isNotNull(short_url);
|
|
assert.strictEqual(original_url, `${url}/?v=${urlVariable}`);
|
|
} else {
|
|
throw new Error(`${res.status} ${res.statusText}`);
|
|
}
|
|
};
|
|
```
|
|
|
|
When you visit `/api/shorturl/<short_url>`, you will be redirected to the original URL.
|
|
|
|
```js
|
|
async (getUserInput) => {
|
|
const url = getUserInput('url');
|
|
const urlVariable = Date.now();
|
|
const fullUrl = `${url}/?v=${urlVariable}`
|
|
let shortenedUrlVariable;
|
|
const postResponse = await fetch(url + '/api/shorturl/new/', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
body: `url=${fullUrl}`
|
|
});
|
|
if (postResponse.ok) {
|
|
const { short_url } = await postResponse.json();
|
|
shortenedUrlVariable = short_url;
|
|
} else {
|
|
throw new Error(`${postResponse.status} ${postResponse.statusText}`);
|
|
}
|
|
const getResponse = await fetch(
|
|
url + '/api/shorturl/' + shortenedUrlVariable
|
|
);
|
|
if (getResponse) {
|
|
const { redirected, url } = getResponse;
|
|
assert.isTrue(redirected);
|
|
assert.strictEqual(url,fullUrl);
|
|
} else {
|
|
throw new Error(`${getResponse.status} ${getResponse.statusText}`);
|
|
}
|
|
};
|
|
```
|
|
|
|
If you pass an invalid URL that doesn't follow the valid `http://www.example.com` format, the JSON response will contain `{ error: 'invalid url' }`
|
|
|
|
```js
|
|
async (getUserInput) => {
|
|
const url = getUserInput('url');
|
|
const res = await fetch(url + '/api/shorturl/new/', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
body: `url=ftp:/john-doe.org`
|
|
});
|
|
if (res.ok) {
|
|
const { error } = await res.json();
|
|
assert.isNotNull(error);
|
|
assert.strictEqual(error.toLowerCase(), 'invalid url');
|
|
} else {
|
|
throw new Error(`${res.status} ${res.statusText}`);
|
|
}
|
|
};
|
|
```
|
|
|
|
# --solutions--
|
|
|
|
```js
|
|
/**
|
|
Backend challenges don't need solutions,
|
|
because they would need to be tested against a full working project.
|
|
Please check our contributing guidelines to learn more.
|
|
*/
|
|
```
|