Skip to content

maxbarsukov/tollowy-api

Repository files navigation

Welcome to ƒolloʍʎ 🔮👋

Yet Another Followy API built with Rails 7

Made with Rails Code style: rubocop
Semaphore CI CI Build Status Docker Build Status
CodeFactor GuardRails Dependabot
CodeClimate Maintainability CodeClimate Test Coverage

Table of contents

  1. Technologies
  2. Getting Started
    1. Pre-reqs
    2. Building and Running
    3. Tuning
  3. Available Scripts
  4. Testing
  5. Linting
  6. Tools
  7. Other
  8. Contributing
  9. Code of Conduct
  10. License

Technologies

Made with: Ruby Made with: Rails Made with: RSpec

Made with: Redis Made with: PostgreSQL Made with: Elasticsearch

Made with: Swagger Made with: Docker Made with: Nginx

Getting Started

Pre-reqs

Make sure you have git installed.

To build and run this app locally you will need a few things:

  • Use Unix-like OS;
  • Install ImageMagick (tested with 7.1.0-44);
  • Check you have Cron installed (tested with cronie 1.6.1);
  • Install Ruby (strictly higher 3.1.2);
  • Install Ruby on Rails (7.0.3);
  • Install PostgreSQL (tested with 14.3);
  • Install Redis (tested with 7.0.0);
  • Install JDK (tested with OpenJDK 17);
  • Install Elasticsearch (tested with 8.2.0);
  • Check you have cgroups V2 with memory controller (otherwise there will be ElasticSearch error);
  • Install Nginx (tested with 1.20.2);

or

Clone this repository:

git clone git@github.com:maxbarsukov/tollowy-api.git

Install dependencies:

bundle install

Overcommit

Setup git hooks:

overcommit --install

CrystalBall

Setup CrystalBall for regression test selection :

CRYSTALBALL=true DONT_GENERATE_REPORT=true bin/tests

PgHero

To setup PgHero you should enable query stats. Add the following to your postgresql.conf:

shared_preload_libraries = 'pg_stat_statements'
pg_stat_statements.track = all
pg_stat_statements.max = 10000
track_activity_query_size = 2048

Then restart PostgreSQL. As a superuser from the psql console, run:

CREATE extension pg_stat_statements;
SELECT pg_stat_statements_reset();

For security, Postgres doesn’t allow you to see queries from other users without being a superuser. However, you likely don’t want to run PgHero as a superuser. You can use SECURITY DEFINER to give non-superusers access to superuser functions.

With a superuser, run:

$ psql -U postgres -d tollowy_production -a -f bin/pghero-permissions.sql -v pghero_password="'pghero_user_password'" -v database_name=tollowy_production
$ psql -U postgres -d tollowy_development -a -f bin/pghero-permissions.sql -v pghero_password="'pghero_user_password'" -v database_name=tollowy_development

Elasticsearch

Add to elasticsearch.yml

http.cors.allow-origin: "/.*/"
http.cors.enabled: true

network.bind_host: 0.0.0.0
network.host: localhost
discovery.type: single-node

Whenever

To use whenever gem you should have cron installed. Run whenever --update-crontab <identifier_name> to update your crontab. Use --set 'environment=production argument to set environment.

Need more detailed installation instructions? We have them.

Building and Running

Locally

Development:
  1. Check you have installed and configured PostgreSQL;
  2. Change DATABASE_HOST and other database data in .env file;
  3. Run bundle exec rails db:create to create database;
  4. Run bundle exec rails db:migrate to run migrations;
  5. Optional: Run bundle exec rails db:seed to seed database;
  6. Check you have installed and configured Redis (ping-pong works);
  7. Check you can start Sidekiq;
  8. Check you have installed and configured Elasticsearch (curl localhost:9200 or your own Elastic URL works);
  9. Setup Elasticsearch username & password and changr .env file if needed;
  10. Run bundle exec rails searchkick:reindex:custom:all to reindex your models;
  11. Configure and start Nginx if needed;
  12. Generate crontab with bundle exec whenever --update-crontab tollowy_development;

Finally, run foreman start and check your http://localhost:3000 (or :80 if you use Nginx)

Production:
  1. Repeat 1-12 steps from development guide.
  2. Configure your .env file and run bin/setup-production;
  3. Execute bin/docker-init.sql and bin/pghero-permissions.sql in psql console on your production database;

Finally, run foreman start -f Procfile to start server in production mode;

Docker

  • Run bin/docker-setup to setup your .env.docker file anf build containers.
  • Use bin/docker-dev-server to run server in dev mode with mailcatcher.
  • Use bin/docker-prod-server to run server in production mode.

Tuning

Some ENV settings you can use at self-hosted Followy API:

Rack::Attack

  • FULL_IP_BAN (false is default):

    • Description: Ban ANY requests for all IPs that are marked as blocked
    • Usage: FULL_IP_BAN=true at .env file or on server start
  • DISABLE_RACK_ATTACK (false is default):

    • Description: Disable Rack::Attack in production
    • Usage: DISABLE_RACK_ATTACK=true at .env file or on server start

Mailing

  • MAIL_USERNAME: Your mail service username;
  • MAIL_PASSWORD: Your mail service password;
  • MAIL_ADDRESS: Your mail service address;
  • MAIL_PORT: Your mail service port;
  • MAIL_DOMAIN: Your mail service domain;
  • MAILER_SENDER_ADDRESS: Your mail sender address (e.g noreply@followy.ru);
  • SMTP_OPENSSL_VERIFY_MODE: Enable/Disable mailer OpenSSL verify mode;

Other

  • CONFIRMATION_TOKEN_LENGTH (40 is default):

    • Description: Set length of generated confirmation token;
    • Usage: CONFIRMATION_TOKEN_LENGTH=N at .env file or on server start
  • RAILS_LOG_TO_STDOUT (false is default):

    • Description: Enables logging to STDOUT in production;
    • Usage: RAILS_LOG_TO_STDOUT=true on server start

Available Scripts

Database

  • rails db:seed – seeds database and exports seeded data to .csv file by default.
    • Use rails db:seed export=false to not generate csv files.
    • Use rails db:seed force=true to seed db even if there is existing data.
  • rails db:seed load=true – loads data to database from db/fixtures/*.csv files.
  • rails db:kill_postgres_connections – Kills all PostgreSQL connections.
  • rails pghero:analyze – Run PgHero database analyzer.
  • rails pghero:rails pghero:autoindex – Run PgHero auto-indexer.
  • rails pghero:capture_query_stats – Run PgHero capture query stats.
  • rails pghero:capture_space_stats – Run PgHero capture space stats.

Elasticsearch

  • rake searchkick:reindex:all – Reindex all models with default Searchkick tool;
  • rake searchkick:reindex:custom:all – Custom models reindex with eager loading;

Documentation

  • Run bundle exec yardoc to generate app documentation to docs/yard folder;
  • Run bundle exec rails erd to generate domain model diagram;

Sidekiq

  • bin/clear-sidekiq to flush existing Sidekiq data.

Swagger

  • bin/rswag to generate swagger.json file.

Generators

  • swagger_schema:
    • run rails g swagger_schema -h to see help message;
    • Examples:
      • rails g swagger_schema comments/comment --type model – Create model schema;
      • rails g swagger_schema comments/destroy --type response – Create response schema;
      • rails g swagger_schema comments/create --type parameter – Create parameter schema;
  • Annotations:
    • rails annotate_models to annotate models;
    • rails annotate_routes to annotate routes;

Other

  • rails log:clear - Truncates all/specified *.log files in log/ to zero bytes
  • rails middleware - Prints out your Rack middleware stack
  • rails secret - Generate a cryptographically secure secret key
  • rails stats - Report code statistics (KLOCs, etc) from the application or engine
  • rails tmp:clear - Clear cache, socket and screenshot files from tmp/
  • rails tmp:create - Creates tmp directories for cache, sockets, and pids
  • rails zeitwerk:check - Checks project structure for Zeitwerk compatibility

Testing

Locally

Run bin/tests or bundle exec rails spec to launch the test runner.

Docker

Run bin/docker-setup and bin/docker-tests to launch tests runner in Docker;

Linting

Locally

  1. bin/rubocop --parallel to check the quality of code with rubocop;
  2. bin/brakeman --quiet --skip-libs --exit-on-warn --no-pager to run brakeman;
  3. bin/bundle-audit update and bin/bundle-audit to run bundler-audit;
  4. bin/bundle exec rails_best_practices . --spec -c config/rails_best_practices.yml to run rails_best_practices;
  5. bin/bundle exec rake active_record_doctor to run active_record_doctor;

or run it together with bin/quality

Docker

Run bin/docker-setup and bin/docker-quality to launch quality checkers in Docker;

Other

Architecture

Followy API is an ordinary Rails monolithic MVC application.

  • Use interactors to take the logic out of the controller
  • Use payloads to build a response using serialized data from serializers and interactor data;
  • Use decorators to use an object-oriented layer of presentation logic;

Admin & Dev pages

  • /admin/sign_in page and sign in as Admin or Developer;
  • /admin page to use ActiveAdmin dashboard (role ≥ admin);
  • /pghero page to see PgHero dashboard (role = developer);
  • /sidekiq page to see Sidekiq Web dashboard (role = developer);

Localization

All localization files are in the config/locales folder with ru.yml and en.yml files in subfolders;

Default locale is en, available locales - en and ru.

You can change locale with ?locale=ru parameter in API request or Admin dashboard URL

To add your own locale, create yourlang.yml in /locale folder subfolders and update I18n config at config/application.rb file (add new available locale and configure fallbacks).

Rack-mini-profiler

Use URL parameters to enable/disable rack-mini-profiler:

  • ?pp=disable to disable;
  • ?pp=enable to enable;
  • ?pp=help to see help message;

Bullet

Bullet is a Rails gem that helps to detect N+1 queries and unused eager loading;

  • Logs are located at log/bullet.log
  • You can find configuration in config/environment/* config files;

CORS

Cross-Origin Resource Sharing (CORS) configuration placed at config/initializers/cors.rb;

Mail previews

You can preview your mails at /rails/mailers/<mailer_name>;

For example, AuthMailer#password_recovery preview in HTML format with ru locale you can find at /rails/mailers/auth_mailer/password_recovery.html?locale=ru

Monkey-patching

Monkey-patched gems located at config/monkey_patches/*.rb.

Please, use refinements instead of monkey-patching if ypu can;

Cron

  • Logs are located at log/cron_log.log
  • Update crontab with bundle exec whenever --update-crontab tollowy_development;

Profiling

  • Use ruby-prof to profile application.
  • Use ProfilingTool class to profile requests;
  • You can use qcachegrind to visualise profiling information
  • You can use tools/benchmark/populate_db_for_posts_votes_bench.rb to populate database with many users, posts and votes;

Tools

Codacy Codacy Badge
Codecov codecov
Coveralls Coverage Status
CodeClimate CodeClimate Maintainability
CodeClimate Test Coverage
Codefactor CodeFactor
DeepSource DeepSource
DeepSource
Depfu Depfu
Depfu

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/maxbarsukov/tollowy-api. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

Code of Conduct

Everyone interacting in the Tollowy project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

License

The gem is available as open source under the terms of the MIT License. Copyright 2022 Tollowy