API: To setup app use 'docker-compose up' command in 'test-api' folder
CLI: To setup cli use 'go install charge' commang in 'test-cli' folder
CLI: execute 'charge post organizations --authorization=HARDCODED_API_KEY --body=body.json --data=full'
Design and code a two endpoint API Server using the following specs:
POST /organizations?data=full&process=true
GET /organizations?data=full
To Submit your solution:
-
clone this repo
-
push your solution to a public repo
Server
Database
Message Queue
Suggested
Docker and Docker Compose for orchestration
Request Body
{
"identifier": "niels.bohr@charge.io",
"businessName": "Charge Technology Group, Inc",
"dba": "Charge",
"ein": "1234567",
"businessType": "corporation",
"bankAccountType": "checking",
"businessStreetAddress": "1100 Highland Ave",
"businessCity": "Manhattan Beach",
"businessState": "CA",
"businessZip": "90266",
"businessCountry": "US",
"contactFirstName": "Ira",
"contactLastName": "Karaba",
"contactTitle": "President",
"contactPhone": "3237178850",
"contactEmail": "ira@charge.io",
"website": "https://charge.io",
"ip": "76.171.141.40",
"deviceFingerprint": "3093vne0ig4n048gweviasefv4oinveslkefjelkjfe",
"meta": {
"key": "value"
},
"additionalChecks": [
{
"name": "bankVerification",
"data": {
"type": "checking",
"account_number": "1234567",
"routing_number": "1234567"
}
}
]
}
Authorization
- Provide a hard coded API Key for authentication
Query Parameters
- if
process=true
place the request body in the bullmq message queue. Thequeue
worker should then add thePROCESSED
status to thestatusHistory
array in the response:
{
"status": "PROCESSED",
"user": {
"id": "775671ff-f70d-415d-b523-f50b05139ac9",
"identifier": "admin@admin.com"
},
"createdAt": "2020-04-20T03:11:23.762Z"
}
- if
process=false
simply return the response, do not add the extra status since the job is not added to thequeue
- if
data=none
, thedata
object in the response should be empty - if
data=base64
, thedata
object in the response should be the request body in base 64 encoded - if
data=full
, thedata
object in the response should be the entire request body
Request Body
- for the
POST
request body, simply use the body provided in the spec - validate data structure to see if fields are not provided
Response Object
For the response of the POST
and GET
requests:
- if
process=true
:
the result
object in the response should be:
{
"id": "f1207990-fae1-4208-b6f1-98ecfc5c6f44",
"identifier": "niels.bohr@charge.io",
"source": {
"method": "api",
"version": "1.0",
"user": {
"id": "775671ff-f70d-415d-b523-f50b05139ac9",
"identifier": "admin@admin.com"
},
"createdAt": "2020-04-20T03:11:23.732Z"
},
"data": {
"organization": {
"id": "f1207990-fae1-4208-b6f1-98ecfc5c6f44",
"accountId": "15b55f81-a6a4-434d-ba9d-c3778d7b3a1b",
"externalId": null,
"identifier": "niels.bohr@quantum.com",
"businessName": "Charge Technology Group, Inc",
"dba": "Charge",
"ein": "1234567",
"businessType": "corporation",
"bankAccountType": "checking",
"businessStreetAddress": "1100 Highland Ave",
"businessCity": "Manhattan Beach",
"businessState": "CA",
"businessZip": "90266",
"businessCountry": "US",
"contactFirstName": "Ira",
"contactLastName": "Karaba",
"contactTitle": "President",
"contactPhone": "3237178850",
"contactEmail": "ira@charge.io",
"website": "https://charge.io",
"ip": "76.171.141.40",
"deviceFingerprint": "3093vne0ig4n048gweviasefv4oinveslkefjelkjfe",
"meta": {
"key": "value"
},
"additionalChecks": [
{
"name": "bankVerification",
"data": {
"type": "checking",
"account_number": "1234567",
"routing_number": "1234567"
}
}
],
"people": [],
"createdAt": "2020-04-20T03:11:23.698Z",
"updatedAt": "2020-04-20T03:11:23.698Z"
}
},
"result": {
"status": "PROCESSED",
"codes": [],
"statusHistory": [
{
"status": "PROCESSED",
"user": {
"id": "775671ff-f70d-415d-b523-f50b05139ac9",
"identifier": "admin@admin.com"
},
"createdAt": "2020-04-20T03:11:23.762Z"
},
{
"status": "PROCESSING",
"user": {
"id": "775671ff-f70d-415d-b523-f50b05139ac9",
"identifier": "admin@admin.com"
},
"createdAt": "2020-04-20T03:11:23.762Z"
},
{
"status": "CREATED",
"user": {
"id": "775671ff-f70d-415d-b523-f50b05139ac9",
"identifier": "admin@admin.com"
},
"createdAt": "2020-04-20T03:11:23.762Z"
}
],
"checks": [],
"createdAt": "2020-04-20T03:11:23.733Z"
},
"notes": [],
"updatedAt": "2020-04-20T03:11:23.698Z",
"createdAt": "2020-04-20T03:11:23.698Z"
}
- if
process=false
:
the result
object in the response should be:
{
"id": "f1207990-fae1-4208-b6f1-98ecfc5c6f44",
"identifier": "niels.bohr@charge.io",
"source": {
"method": "api",
"version": "1.0",
"user": {
"id": "775671ff-f70d-415d-b523-f50b05139ac9",
"identifier": "admin@admin.com"
},
"createdAt": "2020-04-20T03:11:23.732Z"
},
"data": {
"organization": {
"id": "f1207990-fae1-4208-b6f1-98ecfc5c6f44",
"accountId": "15b55f81-a6a4-434d-ba9d-c3778d7b3a1b",
"externalId": null,
"identifier": "niels.bohr@quantum.com",
"businessName": "Charge Technology Group, Inc",
"dba": "Charge",
"ein": "1234567",
"businessType": "corporation",
"bankAccountType": "checking",
"businessStreetAddress": "1100 Highland Ave",
"businessCity": "Manhattan Beach",
"businessState": "CA",
"businessZip": "90266",
"businessCountry": "US",
"contactFirstName": "Ira",
"contactLastName": "Karaba",
"contactTitle": "President",
"contactPhone": "3237178850",
"contactEmail": "ira@charge.io",
"website": "https://charge.io",
"ip": "76.171.141.40",
"deviceFingerprint": "3093vne0ig4n048gweviasefv4oinveslkefjelkjfe",
"meta": {
"key": "value"
},
"additionalChecks": [
{
"name": "bankVerification",
"data": {
"type": "checking",
"account_number": "1234567",
"routing_number": "1234567"
}
}
],
"people": [],
"createdAt": "2020-04-20T03:11:23.698Z",
"updatedAt": "2020-04-20T03:11:23.698Z"
}
},
"result": {
"status": "PROCESSING",
"codes": [],
"statusHistory": [
{
"status": "PROCESSING",
"user": {
"id": "775671ff-f70d-415d-b523-f50b05139ac9",
"identifier": "admin@admin.com"
},
"createdAt": "2020-04-20T03:11:23.762Z"
},
{
"status": "CREATED",
"user": {
"id": "775671ff-f70d-415d-b523-f50b05139ac9",
"identifier": "admin@admin.com"
},
"createdAt": "2020-04-20T03:11:23.762Z"
}
],
"checks": [],
"createdAt": "2020-04-20T03:11:23.733Z"
},
"notes": [],
"updatedAt": "2020-04-20T03:11:23.698Z",
"createdAt": "2020-04-20T03:11:23.698Z"
}
- the
source
object should indicate what user sent the request - the
checks
array in the response should be empty - the
notes
array in the response should be empty - use valid time stamps
- note how when
process=false
thestatusHistory
does not have thePROCESSED
status
Response Status
POST
- Only code for
201
,400
, and401
.
GET
- Only code for
200
and401
.
Data Structures
You can organize the data structures in any way you want.
Write a one command cli in go that allows for making the post request:
charge post organizations --authorization=MY_API_KEY --body=body.json
How would you scale this API to process millions of requests?
What you think would make this API more secure or easily extensible?