The purpose of this API is to learn about REST APIs by developing one using the Express API Skeleton.
A pizza recipe, very broadly, usually includes a recipe for the dough, the toppings used, and other instructions for baking and preparing the pizza. This API tracks pizza recipes along with the dough recipes and toppings used to create them, allowing users to query for information like a specific pizza recipe, the pizzas made using a specific dough recipe, or the pizzas made using a certain topping or combination of toppings.
-
Install Node.js from nodejs.org.
-
Generate a self signed certificate with OpenSSL:
$ openssl req -newkey rsa:2048 -new -nodes -keyout key.pem -out csr.pem $ openssl x509 -req -days 365 -in csr.pem -signkey key.pem -out server.crt
-
Document API design in openapi.yaml. Please keep in mind that openapi documentation is mainly for the client's view. Directly implement the feature in the API if there is any difference between what the client should expect and what our server should provide.
-
Copy config/default-example.yaml to
config/default.yaml
. Modify as necessary, being careful to avoid committing sensitive data. If you want to configure application through custom environment variables, copy config/custom-environment-variables-example.yaml asconfig/custom-environment-variables.yaml
and map the environment variable names into your configuration structure.Environment variables: Sensitive data and data that changes per environment have been moved into environment variables. Below is a list of the variables along with a definition:
Environment variable Description ${API_HOSTNAME}
API hostname. ${API_PORT}
The port used by the API. ${API_ADMIN_PORT}
The port used by the ADMIN endpoint. ${API_USER}
The HTTP Basic username used to authenticate API calls. ${API_PASSWD}
The HTTP Basic password used to authenticate API calls.
5 Copy db/mock-data-example.json to db/mock-data.json
. This will serve as the JSON DB, which is not committed to source code as it will change as the POST endpoint is used.
$ npm install
Run the application:
# Build and run the app
$ gulp devRun
# Run the app without building
$ gulp start
Run ESLint to check the code:
# Using gulp
$ gulp lint
# Using npm
$ npm run lint
Note: We use Airbnb's style as a base style guide. Additional rules and modifications can be found in .eslintrc.yml.
Run unit tests:
# Using gulp
$ gulp test
# Using npm
$ npm test
This API is configured to use Flow static type checking.
Check flow types:
# Using gulp
$ gulp typecheck
# Using npm
$ npm run typecheck
This API uses Babel to transpile JavaScript code. After running, the transpiled code will be located in dist/
. Source maps are also generated in the same directory. These contain references to the original source code for debugging purposes.
Babel allows for newer ECMAScript syntax such as import
and export
from ES6. It also allows Babel plugins to be used.
Compilation is done by the babel
gulp task. This is handled automatically by other tasks but can be manually invoked:
# Using gulp
$ gulp babel
# Using npm
$ npm run babel
This skeleton uses
babel-plugin-module-resolver to resolve
paths. The list of functions that use this plugin can be found in
babel.config.js under transformFunctions
.
Note:
proxyquire
is included but only the path given by the first argument to this function will resolve correctly. The keys for each dependency path in the second argument must be relative paths.
-
Clone the skeleton:
$ git clone --origin skeleton git@github.com:osu-mist/express-api-skeleton.git <my-api>
-
Rename project by modifying package.json.
-
We use express-openapi to generate API by inheriting openapi.yaml. Create path handlers and put them into corresponding directories. For example:
- The path handler for
/src/api/v1/pets
should go to src/api/v1/paths/pet.js - The path handler for
/src/api/v1/pets/{id}
should go to src/api/v1/paths/pet/{id}.js
- The path handler for
-
Copy src/api/v1/serializers/pets-serializer.js to
src/api/v1/serializers/<resources>-serializer.js
and modify as necessary:$ cp src/api/v1/serializers/pets-serializer.js src/api/v1/serializers/<resources>-serializer.js
-
Add the skeleton as a remote:
$ git remote add skeleton git@github.com:osu-mist/express-api-skeleton.git
-
Fetch updates from the skeleton:
$ git fetch skeleton
-
Merge the skeleton into your codebase:
$ git checkout feature/CO-1234-branch $ git merge skeleton/master $ git commit -v
The following instructions show you how to get data from external endpoints for use in the API.
-
Define
dataSources/http
section in the/config/default.yaml
to be like:dataSources: dataSources: ['http'] http: url: 'https://api.example.com'
-
Copy src/api/v1/db/http/pets-dao-example.js to
src/api/v1/db/http/<resources>-dao.js
and modify as necessary:$ cp src/api/v1/db/http/pets-dao-example.js src/api/v1/db/http/<resources>-dao.js
-
Make sure to use the correct path for the new DAO file at path handlers files:
import petsDao from '../db/http/<resources>-dao';
The following instructions show you how to connect the API to an Oracle database.
-
Install Oracle Instant Client by following this installation guide. IMPORTANT: Download the Basic Package, not the Basic Light Package.
-
Install oracledb via package management:
$ npm install oracledb
-
Define
dataSources/oracledb
section in the/config/default.yaml
to be like:dataSources: dataSources: ['oracledb'] oracledb: connectString: 'DB_URL' user: 'DB_USER' password: 'DB_PASSWD' poolMin: 4 poolMax: 4 poolIncrement: 0:
Options for database configuration:
Option Description poolMin
The minimum number of connections a connection pool maintains, even when there is no activity to the target database. poolMax
The maximum number of connections that can be open in the connection pool. poolIncrement
The number of connections that are opened whenever a connection request exceeds the number of currently open connections. Note: To avoid
ORA-02396: exceeded maximum idle time
and prevent deadlocks, the best practice is to keeppoolMin
the same aspoolMax
. Also, ensure increasing the number of worker threads available to node-oracledb. The thread pool size should be at least equal to the maximum number of connections and less than 128. -
If the SQL codes/queries contain intellectual property like Banner table names, put them into
src/api/v1/db/oracledb/contrib
folder and use git-submodule to manage submodules:-
Add the given repository as a submodule at
src/api/v1/db/oracledb/contrib
:$ git submodule add <contrib_repo_git_url> src/api/v1/db/oracledb/contrib
-
Fetch the submodule from the contrib repository:
$ git submodule update --init
-
-
Copy src/api/v1/db/oracledb/pets-dao-example.js to
src/api/v1/db/oracledb/<resources>-dao.js
and modify as necessary:$ cp src/api/v1/db/oracledb/pets-dao-example.js src/api/v1/db/oracledb/<resources>-dao.js
-
Make sure to use the correct path for the new DAO file at path handlers files:
import petsDao from '../db/oracledb/<resources>-dao';
The following instructions show you how to get data from an AWS S3 bucket
-
Install aws-sdk via package management:
$ npm install aws-sdk
-
Define the
dataSources
field inconfig/default.yaml
to be like:dataSources: dataSources: ['awsS3'] awsS3: bucket: BUCKET_NAME apiVersion: API_VERSION accessKeyId: ACCESS_KEY_ID secretAccessKey: SECRET_ACCESS_KEY region: REGION endpoint: null s3ForcePathStyle: false
Options for configuration:
Option Description bucket
The name of the AWS S3 bucket to use apiVersion
Version of the S3 API. Example: '2006-03-01'
endpoint
When using a local or proxy S3 instance, set this value to the host URL. Example: http://localhost:9000
s3ForcePathStyle
Set to true
if using a local or proxy S3 instance -
Copy src/api/v1/db/awsS3/pets-dao-example.js to
src/api/v1/db/awsS3/<resources>-dao.js
and modify as necessary:$ cp src/api/v1/db/awsS3/pets-dao-example.js src/api/v1/db/awsS3/<resources>-dao.js
-
Make sure to use the correct path for the new DAO file at path handlers files:
import petsDao from '../db/awsS3/<resources>-dao';