Skip to content

Repository files navigation

Synthesizer API 🎹

🔥Synthesizer API Explorer!🔥
🔥Synthesizer Directory🔥 🔥Synthesizer Directory repo🔥

For all you gearslutz out there! This free API is the only one out there (since I checked). Explore over 800 synthesizers from past and present. Get insight in their manufacturers and specifications. The API builds upon the data available on the vintagesynthexplorer website. Future work will be aimed to broaden querying options and let you fellow synth lovers contribute to the collection.


Growing as a Developer:

For Usage:


About this Project


The goal of this project is to build an public REST API 🎯 and thereby applying existing knowledge and explore new terrains. This was done independently by reading documentation, watching online videos, consulting StackExchange & sometime my coach.

Although this project aimed at making a public API, I obviously tried it out myself! Therefore I made a frontend that uses it. In development some features where added to the backend as well. Such as a route to suggest synthesizer and an admin login system.


Be sure to visit this deployed version as well: 🔥Synthesizer Directory🔥

This repo contains three main folders:


SCRAPER

The scraper folder contains DOM oriented programming. Before I could fill the database with synthesizers, manufacturers & specification I needed to scrape data. My source also had images, therefore I needed to download images from their respective URL's. After scraping the data it needed to be normalized to fit the SQL database structure. For this, some JS object/string manipulation was used.

SERVER

This folder is the heart of the project. It contains the server (with database). You will find endpoints (& queries) making use of validation middlewares (& Yup). People are able to suggest synths that can get approved through an admin login-system. Look around in authorization (& authorization in model) done through Express middlewares with JWT tokens. The development was mostly fuelled by end-to-end testing. Another thing that needed to be done was migrating images to Cloudinary db and save the image URL's to the main SQL database.

CLIENT

Here you can find the Synthesizer API explorer repo, done with ReactApp. Through the explorer an apikey can be sent to your email. It utilizes frontend validation(with React Hook Form) and some storage concepts(useContext) for the apikey. :fire:Go to API explorer!🔥



Leading topics:


ENVIRONMENTS

Throughout the project we have used: development, testing and production environments. Switching in/out sources and storing key's and secret's in .env and hosts. Wrapping my head around it was challenging at first. Now I feel comfortable to apply this in real world situations.


END-TO-END TESTING

All end-point have been thoroughly tested. The testing formed the basis of development Checking if correct responses were sent & testing all possible 'un-happy' paths was an endevour. But it pays out by making me feel safe to refactor code. Jest and Supertest were used in de backend, Jest & Playwright (like Puppeteer) in the frontend.


VALIDATION & ERROR HANDLING

Validation was done with Yup, used in the backend as well as the frontend. Together with middlewares to safeguarded the routes from user errors and send meaningful feedback to the client when they do occur. Also validated in the backend: multipart/form-data & attachments.


AUTHENTIFICATION & PASSWORD HASHING

To be able to control the flow of user suggested synthesizers I implemented a admin login-system with JWT token. Although this was not my first encounter with this, it was the first time that I implemented it inside of my model and validated the expiration of the token. Hashing/comparing of the user's password was another thing that was done, also inside the model directly.


Things I've done in the backend:

DOM manipulationdownloading images ⭐managing multiple dsb’snormalizing data
generating tablesrelating tablesmocking seed data ⭐using environments ⭐
managing secretsdeployingwriting npm scriptsbig O notation ⭐
end-to-end testing ⭐paginationvalidationsending emails ⭐
writing middlewaresrouting middlewarescontinuous Integration ⭐error handling
CORShandling FormDataHTTP methods (all)Netlify
HerokuJSDOMYup ⭐Express
Cloudinary (db) ⭐Sendgrid ⭐JestSupertest ⭐
Sequelize ORMElephantSQLSQLJWT
custom PromisesExpressNode.js


Things I've done in the frontend:

React DOM routingBootstrap ⭐Sasscaching ⭐
copy to clipboardcustom HooksUseContext ⭐local storage
React children ⭐validationerror handlingfetching data

New technologies learned in this project


User Stories

  • As a Developer that uses this API I want to be able to fetch manufacturers and synthesizer with their specifications, so I can use the API where it is meant for

  • As a Developer that uses this API I want to be able to fetch images of the synthesizers, so I can make something visual I my frontend

  • As a Developer that uses this API I want to be able to know what mistakes I made when I did something wrong in fetching the data,so I can adjust my query and still find the data I'm looking for

  • As a Developer that uses this API I want to be able to paginate and limit the results I'm getting, so I can easily built this in my frontend

  • As a Developer that uses this API I want to be able to query a specific synthesizer either by id or by name, so I'm not restricted to using two endpoint that share one purpose

  • As a Developer that uses this API I want to get the results sorted by year that the synthesizers where produced, so I can easily implement this behaviour when building the frontend

  • As a Developer that uses this API Explorer I want to be able to request apikey through email, so I can explore this API

  • As a Developer that uses this API Explorer I want to be able to view the JSON data retrieve from the URL, so I will see the data that is available

  • As a Developer that uses this API Explorer I want to be able to easily create the URL with route, params and query, so I will find the data that is available

  • As a Developer that uses this API Explorer I want to get suggestions of the endpoint, params and queries I'm aloud to enter, so I know what routes, params and queries are available

  • As a Developer that uses this API Explorer I want to be able to store the apikey across sessions, so I don't have to bother checking my email to find it

  • As a Developer that uses this API Explorer I want to copy the explorer URL to my clipboard so, I can quickly use it outside of the Synthesizer API Explorer

the following stories are derived form the Synthesizer Deirectory frontend build upon this API at later stage

  • As a User of the Synthesizer Directory I want to be able to suggest new synthesizers, so I can contribute to the collection

  • As Myself I want to be able to judge the suggested synthesizer, so I can decide which one's will be added to the collection


Project Board

  • You can find it here.

Wireframes API Explorer


Datamodel

  • Checkout the datamodel used as base for data structure.

Git Version Control

...





Usage


API key

For each request send, you have to send your API key with it. It can be obtained through registering your email at API explorer. The API key can be located anywhere inside the query string. The following example requests with and without additional queries are all valid:

.../synths?key=<apiKey>
.../synths?yearProduced=1980&key=<apiKey>
.../synths?key=<apiKey>&yearProduced=1980

Pagination


Calling any API endpoint without a resource ID or name will return a paginated list of available resources for that API. By default, a "page" will contain up to 20 resources. If you would like to change this just add a 'limit' query parameter to the GET request, e.g. ?=60. You can use 'offset' to move to the next page, e.g. ?limit=60&offset=60.

NameResultType
offsetGet all synths/manufacturers with offsetinteger
limitGet all synths/manufacturers with limitinteger


Endpoint: Synthesizers


GET /synths

Get a list of synth resources including their image, manufacturers and ten specifications

NOTE:
Some data is not normalized yet. Some specifications will have a null value.

Example of json resources:

{
"count": 815,
"synths": [
{
"id": 309,
"name": "Native Instruments Pro-53",
"img": "https://res.cloudinary.com/dgte68hwi/image/upload/v1613044108/Native_Instruments_Pro-53.jpg",
"ManufacturerId": 50,
"SpecificationId": 309,
"synthType": null,
"interfaceFeature": null,
"format": null,
"Specification": {
"id": 309,
"polyphony": "32 voices per Instance",
"keyboard": null,
"control": null,
"yearProduced": 2002,
"memory": "512 Programs (8 programs per bank, 8 banks per file, 8 files). Unlimited Files (512 programs) can be created and stored on your computer for virtually unlimited memory.",
"oscillators": "2 Oscillators. Osc. A has sawtooth and pulse waveforms. Osc. B has sawtooth, triangle and pulse waveforms.",
"filter": "24 dB/oct low-pass / high-pass filter with resonance, self oscillation, ADSR envelope",
"lfo": "1 with sawtooth, square and pulse waveforms, MIDI sync, envelope triggering. Assignable to oscillators, filter, etc.",
"effects": "Delay Section creates Multi-Echo, Chorus, Flange effects and is MIDI-syncable"
},
"Manufacturer": {
"id": 50,
"manufacturer": "Native Instruments"
}
},

GET /synths/1

GET /synths/Jupiter-8

Get one synth resource, by either giving it's ID or exact name.

NOTE:
All specifications and the manufacturer are of synth resources are delivered in a request by default. Specifying them specifically in a query is not necessary. Some data is not normalized yet. This makes it only possible to query with exact name matches. Look into future work to see development goals for querying.

NameResultType
manufacturerGet all synths by a given manufacturerstring
yearProducedGet all synths by a given year they hit the marketinteger
polyphonyGet all synths with description of amount of voicesstring
keyboardGet all synths with description of keyboard specificsstring
controlGet all synths with description of given control (e.g. MIDI, CV/GATE)string
memoryGet all synth with description of memorystring
oscillatorsGet all synths with description of oscillatorsstring
filterGet all synths with description of filterstring
lfoGet all synths with description of lfostring
effectsGet all synths with description of effectsstring


Endpoint: Manufacturers


GET /manufacturers

Get a list of manufacturer resources.

GET /manufacturers/1

GET /manufacturers/Roland

Get one manufacturer resource, by either giving it's ID or exact name.




Future Work


This API is a work in process. Future work aims to improve querying, removing and/or adding queriable synth specifications and creating a moderated POST endpoint, to make you able to add to this collection.

PLANNED

NameResultTypeOptions
manufacturerGet all synths produced by a given manufacturerstringname or id
yearProducedGet all synths that hit the market by a given yearintegerrange, asc/dec
polyphonyGet all synths that have a given amount of voicesintegerrange, asc/dec
keyboardGet all synths that have or do not have a keyboardENUMnone/yes
controlGet all synths that are controlled with MIDI and/or CV/GATEENUMMIDI, CV/GATE
oscillatorsGet all synths that have a given amount of oscillatorsintegerrange, asc/dec
oscillatorTypeGet all synths that are either VCO or DCOENUMVCO, DCO
filterGet all synths that contain one or a combination of lowpass, highpass, bandpassENUMlowpass, highpass, bandpass
effectsGet all synths that have or do not have built in effectsENUMnone/yes
typeGet all synths that are either analog, digital or hybridENUManalog, digital, hybrid


Updates


  • Adding sort by year, ascending and descending
  • Adding, merging specification that will be queriable
  • Make querying possible without strictly needing to equal the resource name
  • Sorting sorting by number functionalities used in more than yearProduced alone
  • And there will be more...



About

Public REST API for Synthesizer data, scaped using JSDOM, server made with Express & Sequelize, API Explorer built with React.

Topics

Resources

Stars

8 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages