Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/michal-wrzosek/challenge-api
Challenge API - REST API
https://github.com/michal-wrzosek/challenge-api
api chai express express-js expressjs heroku jwt jwt-authentication jwt-token mocha mongodb mongoose node-js nodejs rest rest-api travis travis-ci travisci typescript
Last synced: about 1 month ago
JSON representation
Challenge API - REST API
- Host: GitHub
- URL: https://github.com/michal-wrzosek/challenge-api
- Owner: michal-wrzosek
- Created: 2019-05-17T20:20:26.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2022-12-30T17:41:14.000Z (almost 2 years ago)
- Last Synced: 2024-05-28T18:21:34.225Z (7 months ago)
- Topics: api, chai, express, express-js, expressjs, heroku, jwt, jwt-authentication, jwt-token, mocha, mongodb, mongoose, node-js, nodejs, rest, rest-api, travis, travis-ci, travisci, typescript
- Language: TypeScript
- Homepage:
- Size: 1.48 MB
- Stars: 1
- Watchers: 3
- Forks: 1
- Open Issues: 22
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Challenge API - REST API
It's a demo API. There is also a [Demo App](https://github.com/michal-wrzosek/challenge-app) using this API.
---
# Documentation
- [Environments](#environments)
- [Authentication](#authentication)
- [Error responses](#error-responses)
- [Routes](#routes):
- [Providers](#providers)
- [Users](#users)
- [Architecture Design](#architecture-design)
- [Development](#development)
- [Seeds](#seeds)## Environments
**Production:**
https://challenge-api-production.herokuapp.com/**Staging:**
https://challenge-api-staging.herokuapp.com/## Authentication
Access to some endpoints is limited. In order to gain access to them you'll need a valid JSON Web Token. This token can be obtained by calling [/api/v1/users/login](#post-userslogin) endpoint. Token is active for 1 hour. When calling protected endpoints you need to attach an Authorization header with your token like this:
```
Header["Authorization"]: "Bearer your_token_here"
```## Error responses
All errors responses are always structured in the same way:
```
Status: 401, 404, 500JSON:
- error:
- message: string
```## Routes
### Providers
This route lets you query "Providers" resource.
#### GET /providers
This endpoint let's you receive a list of Providers. This endpoint needs a valid token to be accessed (Read more: [Authentication](#authentication))
```
GET /api/v1/providers
```**Pagination:**
This endpoint is paginated. 10 records per page by default. (Min 1, max 50)**Filters:**
You can filter results. Check "Parameters" section.**Projection:**
You can select which fields should be returned. All are visible by default. Check "Parameters" section.**Parameters:**
```
Filters query params:
- max_discharges: number
- min: 0
- filters totalDischarges column
- min_discharges: number
- min: 0
- filters totalDischarges column
- max_average_covered_charges: number
- min: 0
- filters avgCoveredCharges column
- min_average_covered_charges: number
- min: 0
- filters avgCoveredCharges column
- max_average_medicare_payments: number
- min: 0
- filters avgMedicarePayments column
- min_average_medicare_payments: number
- min: 0
- filters avgMedicarePayments column
- state: string (ISO 3166-2 Code like "DC")
- filters state columnProjection query params:
- project: string
- one of:
- providerId
- name
- street
- city
- state
- zipcode
- hospitalReferralRegionDesc
- totalDischarges
- avgCoveredCharges
- avgTotalPayments
- avgMedicarePayments
- drgDefinition
- when using this param you can control which field should be returned
- you can project multiple columns like this:
- /api/v1/providers?project=name&project=street
- this will return only "_id", "name" and "street" fields
- "_id" field will always be returnedPagination query params:
- page: number (positive integer to select current page)
- limit: number (integer in range 1 - 50 to select certain nr of records per page)
```**Successful response:**
```
Status: 200JSON:
- data:
- providers: [
- _id: string
- providerId: string
- name: string
- street: string
- city: string
- state: string
- zipcode: string
- hospitalReferralRegionDesc: string
- totalDischarges: number
- avgCoveredCharges: number
- avgTotalPayments: number
- avgMedicarePayments: number
- drgDefinition: string
]
- pagination:
- totalDocs: number
- limit: number
- page: number
- totalPages: number
- prevPage: number | null
- nextPage: number | null```
### Users
This route is exposed just for authentication purposes. There are no resources you can retrieve.
#### POST /users/login
This is an authentication endpoint that lets you receive JSON Web Token. [More about authentication](#authentication)
**Endpoint:**
```
POST /api/v1/users/login
```**Parameters:**
```
Body (JSON):- email: string (required)
- password: string (required)
```**Successful response:**
```
Status: 200JSON:
- token: JSON Web Token
```**Failed response:**
```
Status: 401JSON:
- error:
- message: "Auth failed"
```#### GET /users/me
This is a token protected endpoint. [More about authentication](#authentication) This endpoint returns current user's data.
**Endpoint:**
```
GET /api/v1/users/me
```**Parameters:**
```
No parameters expected
```**Successful response:**
```
Status: 200JSON:
- user:
- _id: string
- email: string
```**Failed response:**
```
Status: 401JSON:
- error:
- message: "Auth failed"
```---
## Architecture Design
This app was built from scratch (no boilerplate). It's a Typescript project using express.js and mongoose with mongodb. All endpoints were covered by tests. For testing API I used supertest to mock requests to "app". For testing purposes I'm spinning up "mongodb-memory-server" and I'm clearing db for each test. I created a small fixture factory to help me test Providers endpoints. Later on I published an NPM library based on a solution I used building this project - [worp](https://www.npmjs.com/package/worp).
For pagination I used "mongoose-paginate-v2" plugin.
Filtering and projection is made more or less "manually" in a controller.
GitHub repo restricts PRs to master branch to pass Travis CI build.
Master branch is automatically deployed to staging environment on Heroku. Production can be deployed manually.
---
## Development
### Seeds
It is sometimes useful to populate database with some prepared data/fixtures. I created a simple seed CLI runner. Just type:
```bash
npm run seed name_of_seed_here
```#### Create Master User Seed
Since this API does not expose any sign-up endpoint we can create a master user by seeds. Just provide user's email and password via ENV and run a seed.
**ENVs:**
- `MASTER_USER_EMAIL`
- `MASTER_USER_PASSWORD`**Command to run this seed:**
```bash
npm run seed createMasterUser
```#### Populate Providers Seed
For development purposes you can populate your DB with 300 Providers coming from automatically generated fixtures:
```bash
npm run seed populateProviders
```