This is the back-end of the MindCast App.
It's a RESTful API built with NodeJS + Express + MongoDB that receive all the data related with authors and podcats and record/provide to the client all this data through a REST API.
The main purpose of this API is stream audio files, podcasts were selected by me just to give some context to the app. So, you can reuse all this code to upload/stream a audio (just tested with .mp3) file and use inside your own context (music app, your own podcasts or whatever!).
This project is part of my personal portfolio, so, I'll be happy if you could provide me any feedback about the project, code, structure or anything that you can report that could make me a better developer!
Email-me: stenio.wagner1@gmail.com
Connect with me at LinkedIn
Also, you can use this Project as you wish, be for study, be for make improvements or earn money with it!
It's free!
To run this project in the development mode, you'll need to have a basic environment with NodeJS 8+ installed. To use the database, you'll need to have MongoDB installed and running on your machine at the default port (27017).
Cloning the Repository
$ git clone https://github.com/steniowagner/mindcast-server
$ cd mindcast-server
Installing dependencies
$ yarn
or
$ npm install
Now, you'll need to change to development branch:
$ git checkout development
With all dependencies installed, the Database running and the environment properly configured, you can now run the server:
$ yarn dev
or
$ npm run dev
$ yarn test
or
$ npm run test
$ yarn test:coverage
or
$ npm run test:coverage
The base URL is: http://localhost:3001/mind-cast/api/v1/
- This is the route that you can use to check if the API is running properly.
ENDPOINT | Method | Params | URL Params | Success Response | Error Response |
---|---|---|---|---|---|
/ | GET |
- | - | Code: 200 - OK Content: { message: "UHUL! The API is UP && RUNNING!" } |
Code: 500 - INTERNAL SERVER ERROR Content: { error: <A Message with a description of the Error> } |
- Returns a set of of podcasts and authors based on the categories selected by the user.
EX:
http://localhost:3001/mind-cast/api/v1/home?categories=science&categories=history
ENDPOINT | Method | Params | URL Params | Success Response | Error Response |
---|---|---|---|---|---|
/home | GET |
- | categories: Category |
Code: 200 - OK Content: { hottestPodcasts: [Podcast],newReleases : [Podcast],trendingAuthors : [Author]} |
Code: 500 - INTERNAL SERVER ERROR Content: { error: <A Message with a description of the Error> } |
- Returns the podcasts and authors related with the category.
EX:
ENDPOINT | Method | Params | URL Params | Success Response | Error Response |
---|---|---|---|---|---|
/categories/:category | GET |
category: Category |
- | Code: 200 - OK Content: { featured: [Podcast],trending : [Podcast],authors : [Author]} |
Code: 500 - INTERNAL SERVER ERROR Content: { error: <A Message with a description of the Error> } |
- Upload a podcast
For this request, you'll need to send the .mp3 file and all the Podcast data. If you don't know how to send a file using a http client tool, here's an example of how to do it with Postman.
Don't forget to send the fields of the Podcast that are described on the image!
ENDPOINT | Method | Params | URL Params | Success Response | Error Response |
---|---|---|---|---|---|
/authors/:id/podcasts | POST |
id | - | Code: 201 - CREATED Content: { podcast: Podcast } |
Code: 500 - INTERNAL SERVER ERROR Content: { error: <A Message with a description of the Error> } |
- Create an author
ENDPOINT | Method | Params | URL Params | Success Response | Error Response |
---|---|---|---|---|---|
/authors | POST |
Author | - | Code: 201 - CREATED Content: { id: <ID of the Author Created> } |
Code: 500 - INTERNAL SERVER ERROR Content: { error: <A Message with a description of the Error> } |
- Get all authors
ENDPOINT | Method | Params | URL Params | Success Response | Error Response |
---|---|---|---|---|---|
/authors | GET |
- | - | Code: 200 - OK Content: { authors: [Author],} |
Code: 500 - INTERNAL SERVER ERROR Content: { error: <A Message with a description of the Error> } |
- Get a single author
ENDPOINT | Method | Params | URL Params | Success Response | Error Response |
---|---|---|---|---|---|
/authors/:id | GET |
id | - | Code: 200 - OK Content: { author: Author,} |
Code: 404 - NOT FOUND Content: { message: "Author not found." } or Code: 500 - INTERNAL SERVER ERROR Content: { error: <A Message with a description of the Error> } |
- Update an Author
ENDPOINT | Method | Params | URL Params | Success Response | Error Response |
---|---|---|---|---|---|
/authors/:id | PATCH |
Required:Fields that will be updated |
id | Code: 200 - OK Content: { author: Author} |
Code: 404 - NOT FOUND Content: { message: "Restaurant Not Found." } or Code: 500 - INTERNAL SERVER ERROR Content: { error: <A Message with a description of the Error> } |
- Delete an Author
ENDPOINT | Method | Params | URL Params | Success Response | Error Response |
---|---|---|---|---|---|
/author/:id | DELETE |
id | - | Code: 204 - NO CONTENT |
Code: 404 - NOT FOUND Content: { message: "Author not found." } or Code: 500 - INTERNAL SERVER ERROR Content: { error: <A Message with a description of the Error> } |
- Filter by name
EX:
http://localhost:3001/mind-cast/api/v1/authors/filter?name=stark
ENDPOINT | Method | Params | URL Params | Success Response | Error Response |
---|---|---|---|---|---|
/authors/:id | GET |
id | - | Code: 200 - OK Content: { author: Author,} |
Code: 404 - NOT FOUND Content: { message: "Author not found." } or Code: 500 - INTERNAL SERVER ERROR Content: { error: <A Message with a description of the Error> } |
- Get all podcats
ENDPOINT | Method | Params | URL Params | Success Response | Error Response |
---|---|---|---|---|---|
/podcasts | GET |
- | - | Code: 200 - OK Content: { podcasts: [Podcast],} |
Code: 500 - INTERNAL SERVER ERROR Content: { error: <A Message with a description of the Error> } |
- Get a single podcast
ENDPOINT | Method | Params | URL Params | Success Response | Error Response |
---|---|---|---|---|---|
/podcasts/:id | GET |
id | - | Code: 200 - OK Content: { podcast: Podcast,} |
Code: 404 - NOT FOUND Content: { message: "Podcast not Found." } or Code: 500 - INTERNAL SERVER ERROR Content: { error: <A Message with a description of the Error> } |
- Stream a podcast file
ENDPOINT | Method | Params | URL Params | Success Response | Error Response |
---|---|---|---|---|---|
/podcasts/:id/listen | GET |
id | - | Code: 206 - Partial Content Content: Stream of a podcast audio file |
Code: 404 - NOT FOUND Content: { message: "Podcast not Found." } or Code: 500 - INTERNAL SERVER ERROR Content: { error: <A Message with a description of the Error> } |
- Download a podcast file
http://localhost:3001/mind-cast/api/v1/podcasts/:id/download
ENDPOINT | Method | Params | URL Params | Success Response | Error Response |
---|---|---|---|---|---|
/podcasts/:id/download | GET |
id | - | Code: 200 - OK Content: Stream of a podcast audio file |
Code: 404 - NOT FOUND Content: { message: "Podcast not Found." } or Code: 500 - INTERNAL SERVER ERROR Content: { error: <A Message with a description of the Error> } |
{
"enum": "science | technology | philosofy | business | pop-culture | history",
}
podcasts: Author's podcasts.
categories: Categories of the Author.
name: Author's name.
profileImageURL: An URL of an image to represent the Author (you can use some image with more than 600 x 400)
thumbnailProfileImageURL: The same image of
imageURL
, but with a smaller scale (less than (90 x 90))
podcasts: This field isn't required for any request from the user, it will always be sent by the server.
about: A description of the Author.
{
"podcasts": {
"type": "[MONGOOSE.SCHEMA.TYPES.OBJECT_ID]",
"required": false,
"default": [],
},
"categories": {
"type": "[Category]",
"required": true,
},
"name": {
"type": "String",
"required": true,
},
"profileImageURL": {
"type": "String",
"required": true,
},
"thumbnailProfileImageURL": {
"type": "String",
"required": true,
},
"about": {
"type": "String",
"required": true,
},
}
author: ID of the author.
"title": Title of the podcast.
"description": Description of the podcast.
imageURL: An image to represent the podcast (you can use some image with more than 600 x 400)
thumbnailImageURL: The same image of
imageURL
, but with a smaller scale (less than (90 x 90).
category: Category of the podcast.
stars: Stars of the podcast.
duration, durationInSeconds and fileName: These fields are created and sent by the server after to analyze and parse the uploaded audio file, and aren't required for any request.
{
"author": {
"type": "MONGOOSE.SCHEMA.TYPES.OBJECT_ID",
"required": false,
},
"title": {
"type": "String",
"required": true,
},
"description": {
"type": "String",
"required": true,
},
"imageURL": {
"type": "String",
"required": true,
},
"thumbnailImageURL": {
"type": "String",
"required": true,
},
"category": {
"type": "Category",
"required": true,
},
"stars": {
"type": "Number",
"required": true,
},
"duration": {
"type": "String",
},
"durationInSeconds": {
"type": "Number",
},
"fileName": {
"type": "String",
}
}
- NodeJS - Build the server
- Heroku - PaaS used in the production
- TravisCI - CI + CD
- body-Parser - Node.js body parsing middleware
- express - Router of the Application
- MongoDB - Database
- mongoose - Object Modeling + DB Connector
- nodemon - Process Manager used in the development
- dotenv - Environment loader
- multer - File Upload
- gridFS-Stream - Store and stream data from Database
- mp3-Duration - Get the duration of the .mp3 files uploaded
- eslint - JS Linter and code style
- JEST - Tests
- superagent-binary-parser - Parse binary response stream
- coveralls - Test coverage
- faker - Create fake data for tests
- prettier - Code formatter
- super-test - Test HTTP requests
- husky - Git hooks
- lint-staged - Run linters on git staged files
- Image-Resize - Resize the Images
- Amazon S3 - Storage Service
You can send how many PR's do you want, I'll be glad to analyse and accept them! And if you have any question about the project...
Email-me: stenio.wagner1@gmail.com
Connect with me at LinkedIn
Thank you!
This project is licensed under the MIT License - see the LICENSE.md file for details.