Ansel is an API written in TypeScript using the KoaJS framework, providing endpoints to retrieve images/data from S3/B2 buckets.
Ansel is named after Ansel Adams.
These items are what I consider the stepping stones to v1
.
- Full CRUD endpoints
- Basically I want to be able to upload new assets, update existing assets, delete assets, and of course retrieve/get assets.
-
/get
-
/get/:folderName
- Returns a random asset from the folder w/ the same name as the
folderName
parameter.
- Returns a random asset from the folder w/ the same name as the
-
/get/:folderName/:assetId
- Return the asset from the folder w/ the same name as the
folderName
parameter and id matching the givenassetId
parameter.
- Return the asset from the folder w/ the same name as the
-
-
/list
-
/delete
-
/upload
- All endpoints should return the following basic status codes as expected:
- Successful
- 200 - OK
- 201 - Created
- 202 - Accepted
- 203 - Non-Authoritative Information
- 204 - No Content
- 205 - Reset Content
- 206 - Partial Content
- Client Error
- 400 - Bad Request
- 401 - Unauthorized
- 402 - Payment Required
- 403 - Forbidden
- 404 - Not Found
- 405 - Method Not Allowed
- This one is handled by Koa under the hood for us.
- Server Error
- 500 - A generic server error, doesn't fit any of the following codes.
- Successful
- OpenAPI Spec
- I want/need an OpenAPI specification file to make it easier for folks to begin using the API.
- Documentation Site
- Support for both S3 compatible APIs and Backblaze B2 storage methods.
- S3
- B2
- Benchmarks using Artillery or something similar.
- This is more of a wish than a requirement but I'd like to have full monitoring of the various components within Dynatrace and/or Ackee (Theia).
In order to use the Ansel API, you must have a few things already good to go. For example, the S3 bucket which will contain your images should already be setup and an API key to access it generated.
In the repo is a script called start.sh
which will start up a Docker container running the latest version of the Ansel API. The only requirement is that you rename the settings.sample.json
file to settings.json
and populate it with the necessary values. You can now run start.sh
and it'll start the container then begin tailing the logs.
NOTE: Ctrl+C
will stop the tailing/following of the logs so you can get your terminal back.
First up, you need to provide a few environment variables to the Docker image for it to work correctly. The start.sh
script shows exactly what parameters are needed, but we'll go over them here:
appName
⸺APP_NAME
- The display name of the application.
Ansel
by default.
- The display name of the application.
version
⸺VERSION
- The version of the application.
port
⸺PORT
- The port to listen on, defaults to
8080
.
- The port to listen on, defaults to
apiPrefix
⸺API_PREFIX
- The prefix of all endpoints, defaults to
/api/v1
.
- The prefix of all endpoints, defaults to
imgBaseUrl
⸺IMG_BASE_URL
- The URL to append to the beginning of each image URL.
bucketName
⸺BUCKET_NAME
- The name of the bucket containing your images.
bucketEndpoint
⸺BUCKET_ENDPOINT
- The url/endpoint for accessing the s3 API of the given bucket.
bucketAccessKeyId
⸺BUCKET_ACCESS_KEY_ID
- The access key id for the s3 bucket that contains your images.
bucketSecretAccessKey
⸺BUCKET_SECRET_ACCESS_KEY
- The secret access key for the s3 bucket that contains your images.
The easiest way to pass these to the Docker image is to rename the settings.sample.json
file to settings.json
and run the start.sh
script. It will start the Docker container for you using the following command, which we'll break down:
1 docker run -p $PORT:$PORT -d \
2 -e BUCKET_ENDPOINT=$BUCKET_ENDPOINT \
3 -e BUCKET_ACCESS_KEY_ID=$BUCKET_ACCESS_KEY_ID \
4 -e BUCKET_SECRET_ACCESS_KEY=$BUCKET_SECRET_ACCESS_KEY \
5 -e APP_NAME=$APP_NAME \
6 -e VERSION=$VERSION \
7 -e PORT=$PORT \
8 -e API_PREFIX=$API_PREFIX \
9 -e BUCKET_NAME=$BUCKET_NAME \
10 -e IMG_BASE_URL=$IMG_BASE_URL \
11 --name ansel 4lch4/ansel:latest
- The first line is the docker run command, but with the
-d
and-p
parameters.-d
tells Docker to run the container in daemon mode, so that it can run in the background.-p
tells the container the port to assign/forward for the container.
- Lines 2-10 are assigning environment variables using the values from the
settings.json
file. - Line 11 provides the
--name
parameter and then the image with theauthor/image-name:version
format.- The
--name ansel
parameter and value tells Docker what to name the container when it's created. This is what you use when running commands such asdocker stop ansel
ordocker logs ansel
. - The
4lch4/ansel:latest
bit specifies the image to run, which in this case, is the latest ansel image published by 4lch4 (me).
- The
Once the API server is up and running, using the above steps, you can begin calling it and receiving images/data. First things first ports and URLs:
- If you are running the server as is without a reverse proxy then you'll need to append the port number to your URLs.
- If you have a custom apiPrefix be sure to keep that in mind. Otherwise, the default is
/api/v1
.
Once you have the above info, you're able to begin making requests! The following samples utilize the HTTPie CLI utility:
Since images are categorized in folders, the /list
endpoint will return an object containing a count of the folders and an array of those folders in the s3 bucket:
❯ http GET localhost:8080/api/v1/list --check-status
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 460
...
{
"count": 54,
"data": [
"alcha",
...
"whack"
]
}
There are two ways to retrieve images from a given folder: Randomly or Index-based
If you don't care which image is returned, hit the /get
endpoint with the name of the folder:
❯ http GET localhost:8080/api/v1/get/alcha --check-status
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 42
...
https://i.ansel.rest/alcha/alcha-6.png
My personal instance of Ansel has images indexed by filename and each filename has the index number in it. Therefore, retrieving specific images is easy once you know the index/number of the file:
❯ http GET localhost:8080/api/v1/get/alcha/2 --check-status
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 42
...
https://i.ansel.rest/alcha/alcha-2.gif
Since Ansel is designed to be run within Kubernetes it has healthcheck endpoints available by default.
❯ http GET localhost:8080/api/v1/health/liveness --check-status
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 2
...
OK
❯ http GET localhost:8080/api/v1/health/readiness --check-status
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 2
...
OK