MyHearty API powers MyHearty website and MyHearty dashboard. This repository contains the backend implementation of MyHearty API in Ruby on Rails and other backend services. The Rails application is running in API mode and serves JSON resources to the frontend API clients.
You can find the architecture overview in the illustration below, which will give you a good starting point in how the backend services interact with other services.
To get the backend services up and running, read the following subsections.
If you have Docker and Docker Compose installed, you can set up and run the services easily via the provided docker-compose.yml
file.
If you do not want to use Docker Compose, you need to install the following requirements to be able to run the services locally:
- Ruby 3.0+
- PostgreSQL 14.0+
- Redis 6.0+
- Typesense 0.22+
- NGINX 1.21+
The rest of the documentation assumes that you have already installed Docker Compose.
- Clone the repo.
git clone https://github.com/myhearty-org/myhearty-api.git
- Create a
.env
file in the root directory by copying the environment variables from the.env.example
file. You can change versions of the services there. For more information on populating environment variables, refer to the services section. - To start the services using Docker Compose, you can either:
- Run the required services only by specifying the services' names:
docker-compose up -d [service1, service2, ...]
- Run all services:
docker-compose up -d
- Run the required services only by specifying the services' names:
- To start an interactive shell inside any service, run:
This is useful when you want to interact with the service's internal states or run some console commands.
docker-compose exec [service-name] sh
- To stop the services, you can either:
- Stop certain services only by specifying the services' names:
docker-compose stop [service1, service2, ...]
- Stop all services:
docker-compose stop
- Stop certain services only by specifying the services' names:
- To remove the containers together with saved states and start everything from scratch again, run:
docker-compose down -v
Warning
This is a destructive action that will delete all data stored in the PostgreSQL database and Typesense search engine.
Note
If you want to enable any of the available integrations, you may want to obtain additional credentials and populate secrets for the corresponding integration. Refer to the integrations section for more details.
The docker-compose.yml
file contains the following services:
Service | Description | Endpoint |
---|---|---|
api |
The Rails API server | http://localhost:3000 |
db |
The PostgreSQL database | http://localhost:5432 |
typesense |
The Typesense search engine that powers instant search and geosearch in the frontend | http://localhost:8108 |
sidekiq |
The background job scheduler for Ruby | NO ENDPOINT |
redis |
Provides data storage for Sidekiq | http://localhost:6379 |
nginx |
Acts as a reverse proxy server that directs the client requests to either the Rails API server or Typesense based on the request URL | NO ENDPOINT |
Refer to the services' official image repositories for the configuration of environment variables in the docker-compose.yml
file.
Some services require credentials like a password or a bootstrap API key. You can use Ruby's built-in SecureRandom
library to generate a secure random string:
- Open a shell in the
api
container.docker-compose exec api sh
- Generate a random string:
rails c > SecureRandom.alphanumeric(32) # your random string length
The Rails application contains the code required to run the MyHearty API server. If you make changes to the Gemfile
or the docker-compose.yml
file to try out some different configurations, you need to rebuild. If the changes involved Gemfile
like adding/removing gems, you need to:
- Sync changes in the
Gemfile.lock
to the host:docker compose run api bundle install
- Rebuild the images:
docker compose up --build
Other changes require you to run the second command only.
- Populate the following PostgreSQL's related environment variables in the
.env
file before starting the database:POSTGRES_USER= # your DB username POSTGRES_PASSWORD= # your DB password POSTGRES_HOST=postgres # your DB host
- If the variables are not set, the service will use the defaults provided by the PostgreSQL image.
POSTGRES_HOST
is set topostgres
to allow other services to communicate with the database service using network alias. Seedocker-compose.yml#L42
for more detail.
- To create the database, run the following commands:
- Open a shell in the
api
container.docker-compose exec api sh
- Create the database and load the schema:
rake db:create rake db:schema:load
- Open a shell in the
- To seed data, run:
rake db:seed SEEDS_MULTIPLIER=2
- The environment variable
SEEDS_MULTIPLIER
defaults to 1 and controls the amount of data generated by the seeder. - Note that, during seeding, Typesense schema will be deleted and later re-created. Certain resources from the database will be indexed into Typesense to enable instant search. See
01_typesense.rb
for more detail. - The populated data include user credentials and fake image URLs. See
02_resources.rb
to understand what types of data are being populated.
- The environment variable
- To remove data, run:
rake db:truncate
- This command is useful when you want to re-seed the database.
- This is a custom task defined in
db.rake
.
PostgreSQL can be further configured in database.yml
.
Typesense is an open-source, typo-tolerant search engine that is optimized for instant search. It is an easier-to-use alternative for commercial search API like Algolia, which has high pricing, or open-source search engine like Elasticsearch, which can be complicated to tune.
- Generate an API key before starting Typesense.
- Assign the API key to the
TYPESENSE_API_KEY
variable in the.env
file. - To start Typesense, run:
docker-compose up -d typesense
Sidekiq is dependent on Redis as the data storage provider. To enable background processing:
- Generate a password before starting Redis.
- Assign the password to the
REDIS_PASSWORD
variable in the.env
file. - To start Sidekiq, run:
docker-compose up -d redis sidekiq
Sidekiq can be further configured in sidekiq.rb
and sidekiq.yml
.
NGINX acts as a reverse proxy server that directs the client requests to either the Rails API server or Typesense based on the request URL. It can be configured in nginx.conf
.
You can find the source code, demo and documentation for the frontend in the myhearty repository.
To store your credentials for external services securely, you need to create a credentials.yml.enc
file:
- Open a shell in the
api
container.docker-compose exec api sh
- Create the
credentials.yml.enc
file:EDITOR="nano --wait" rails credentials:edit
Note that you need to run these commands every time you want to edit your credentials (for the integrations below).
Stripe is used as the payment processor for donations made on MyHearty. There are 2 services involved: Stripe Connect and Stripe Checkout. Stripe Connect is used to onboard organizations that want to publish fundraising campaigns on MyHearty by collecting their business information, which include business name, location and bank account information. Stripe Checkout provides a hosted payment page that can be customized to securely accept online payments from donors. To enable donations feature:
- Go to Stripe Dashboard to create a Stripe account.
- Refer to Stripe Docs: API Keys and Stripe Docs: Check the webhook signatures to obtain your API secret key and webhook endpoint secret.
- In the
credentials.yml.enc
file, add the following credentials:stripe: secret_key: # your Stripe API secret key webhook_signing_secret: # your webhook endpoint secret
Images can be directly uploaded from browsers to Amazon S3. To enable direct S3 uploads:
- Go to AWS Console to create an AWS account.
- Refer to Shrine GitHub Wiki: Adding Direct S3 Uploads to learn how to add direct S3 uploads to the Rails application.
- In the
credentials.yml.enc
file, add the following credentials:s3: bucket: # your S3 bucket name region: # your S3 bucket region access_key_id: # your access key ID secret_access_key: # your secret access key
Geoapify provides the Geocoding API to convert addresses to latitude/longitude. The backend geocoding process allows the website users to search for volunteer events and aids using the geosearch feature. To enable geocoding:
- Go to Geoapify MyProjects to create an account and generate an API key for your project.
- In the
credentials.yml.enc
file, add the following credentials:geoapify: api_key: # your Geoapify API key
The geocoding API can be configured in geocoder.rb
. Refer to alexreisner/geocoder if you want to use other API providers.
SendGrid is used as the email delivery service for MyHearty API in production mode. To enable email delivery:
- Go to SendGrid Signup to create a SendGrid account.
- Generate an API key with restricted access. Only enable full access for Mail Send access. Refer to SendGrid Docs: API Keys for more detail.
- In the
credentials.yml.enc
file, add the following credentials:sendgrid:: api_key: # your SendGrid API key
The full documentation for the MyHearty project can be found in the myhearty-documentation repository. The documentation repository contains technical documents and architecture information related to the implementation of this project.
If you want to contribute, please fork the repo and create a pull request by following the steps below:
- Fork the repo.
- Create your feature branch (
git checkout -b your-feature-branch
). - Commit your changes and push to the branch (
git push origin your-feature-branch
). - Open a pull request.
Your changes will be reviewed and merged if appropriate.
- Rails Guides: Using Rails for API-only Applications
- Docker Docs: Quickstart: Compose and Rails
- GitHub: Dockerize Rails 7 with ActionCable, Webpacker, Stimulus, Elasticsearch, Sidekiq
- Devise GitHub Wiki: API Mode Compatibility Guide
- GitHub: Accept payments with Stripe Checkout (Ruby Server Implementation)
- Shrine GitHub Wiki: Adding Direct S3 Uploads