GithubHelp home page GithubHelp logo

adamvig / gocoapi Goto Github PK

View Code? Open in Web Editor NEW
0.0 0.0 0.0 194 KB

API Server for the GoCoStudent app.

Home Page: https://gocostudent.adamvig.com/api

License: GNU General Public License v3.0

JavaScript 100.00%

gocoapi's People

Contributors

adamvig avatar

Watchers

 avatar  avatar

gocoapi's Issues

Improve logging

  • Change to human-readable log output
  • Change output level to trace

Add API schema validation tests

The current regression test only checks for 200 OK responses, but does not check if the returned data is in the correct format or of the correct type.

Looks like Chai has a plugin called chai-json-schema that would integrate well with the existing tests written with Mocha.

Add endpoints to interact with User data

Missing:

  • Set Property /setproperty username, password, propertyName, value
    Set a property in a user's doc. Search recursively for property, return descriptive error code if property or user does not exist.
  • Create User /createuser username, password
    Create a user doc in the database, furnished with all necessary fields for initialization.

Add per-request logging

In the old API, every request was logged to the user's doc in the database by incrementing the number of requests the user had made to that endpoint.

This became less relevant when the app gained the autoload feature that requests data for all enabled modules every time the app is opened. It may be more relevant to keep separate global-level and user-level statistics, though the global statistics would be better generated by a logging/analytics platform such as New Relic.

User Statistics

  • Last Login (useful for removing inactive users)
  • Total number of requests
  • Number of requests for each endpoint
  • Device platform
  • Device version

Duplicates #3.

Add a load test to profile API server performance

After some research, it seems that the two best options for programmatic (not command-line) HTTP load testing are:

Artillery is good, but requires that variables for use in requests are defined in CSV files. It would be better for the test library to use exported variables from vars.js, where test credentials are already defined.

It looks like loadtest has a better API.

Add API keys

Instead of allowing unfettered access to the API, restrict access to users with generated API keys.

Improve database support

Currently, the database (the app only supports one database) is abstracted behind a simple interface supporting get and save operations, and nothing else. The database interaction is handled by the nano library. An instance of nano is instantiated in the db module and shared by all modules that depend on it.

Possible improvements:

  • Add support for multiple databases
  • Convert database to a class
  • Add classes for models (Info and User should suffice)
    • Model will be a generic class for handling documents
    • Info and User will extend Model and add methods as well as instantiate the appropriate database for each one using the Database class
  • Add static methods to Model for performing operations on multiple models at once.

Add cache bust parameter to requests

Endpoints should expect a parameter that tells them to skip cached data if it exists.

This allows for more predictable behavior when conducting load and regression tests, which report how long the requests took.

Technical Debt

  • Endpoint names are unnecessarily duplicated between filenames and config.ROUTES. Instead of depending on a list of endpoint names set in config.js, dynamically load endpoints based on their definitions in the routes directory.
  • Endpoints are modular and have little code-duplication, which is a major improvement over the necessary copy-and-pasting to add a new endpoint to the legacy API. However, passing a configuration hash to a centralized function that takes care of creating the endpoints seems backwards. Instead, there should be an Endpoint class defined centrally that is instantiated in each endpoint's definition, and that endpoint should call the function that defines itself on the app object. Exploring ES6's chapter on Classes is an excellent resource on the subject.
  • Testing is severely lacking. The existing regression test is a simplistic approach to ensuring that the API works from the outside, but there is no functional testing to ensure that each function is performing as expected.
    • Test coverage of helper functions located in /helpers.
    • Test coverage of endpoint getter and processor functions with dummy data.
    • Test schema of JSON returned in regression test to ensure that the API is returning the correct types of data.
    • Test API under load conditions.
  • Code formatting is not standardized.
    • Add .jshintrc and .eslintrc and fix all issues that come up (copy files from GoCoStudent).
    • Replace all function () {} with () => {}.
    • Replace any var with either let or const.

Add true API versioning

Currently, each request is sent to /api/[app version], which is helpful but somewhat backwards. Instead, the app should send requests to /api/ with the Accept-Version header, then the API version can be changed and the app will never know the difference.

Restify supports versioned routes out of the box.

API versioning on the request-level should go hand-in-hand with API versioning on the release level, meaning that this project should get on a release schedule using semantic versioning.

Improve error reporting

Instead of returning only a friendly error message as text/plain, return a JSON object containing the following fields:

{
  description: "Actual description of error message for debugging purposes"
  message: "User-facing message, ex: Something went wrong! ๐Ÿ†˜ "
}

This change should also come with more descriptive use of error codes.

Fix mealpoints

 InternalServerError: Error: getaddrinfo ENOTFOUND my.gordon.eduundefined my.gordon.eduundefined:443
        at Object.utils.handleError (/var/www/gocoapi/helpers/utils.js:30:17)
        at getData.then.then.catch (/var/www/gocoapi/routes/endpoint.js:91:27)

Fix caching support

Currently, the cacheGlobal() method in cache.js is unused, and global caching seems to be entirely disabled. The whole file could be refactored to be clearer, as well.

This depends on #4 "Run CouchDB on server instead of externally", because testing the global cache would require modifying documents in the actual database (issue is now closed).

Change to MySQL

CouchDB leaves a lot to be desired. Its basic functionality is good, but it fails in two major areas:

  1. querying: map and reduce functions are a hassle compared to SQL
  2. space efficiency: since GoCo updates the database frequently, CouchDB takes up large amounts of storage with old revisions of documents

The advantage of CouchDB is quick and dirty data modelling. For example, it will be a challenge to convert the Highland Express data to a relational schema.

CouchDB is also a practical, if improper, solution for caching data. MySQL makes that much more difficult, so Etags and the Expires header should be used in place of a homegrown caching solution.

Using MySQL will make it easier to reduce data duplication. Instead of storing a number of requests for each endpoint and a total number of requests, the new schema can store just the number of requests per endpoint. A view can be created to sum the total number of requests for each user and the total number of requests for each endpoint.

A view can also be created to calculate the date and time of each user's last request based on a timestamp in the endpoint usage table.

A simple first attempt at a schema:
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.