1
0

Implemented a 3 endpoint json api storing and querying data from neo4j

This commit is contained in:
Miguel Salgado 2023-05-23 20:47:11 -07:00
parent 07d3ad1329
commit a321111640
13 changed files with 189 additions and 30 deletions

View File

@ -1,6 +1,6 @@
FROM ruby:3.2.2
RUN mkdir -p /var/app
COPY . /app
WORKDIR /app
COPY Gemfile Gemfile
RUN bundle install
CMD rails server -e development -b 0.0.0.0 --log-to-stdout
COPY . /app
CMD rails server -b 0.0.0.0 --log-to-stdout

20
Gemfile
View File

@ -13,16 +13,7 @@ gem "sqlite3", "~> 1.4"
gem "puma", "~> 5.0"
# Build JSON APIs with ease [https://github.com/rails/jbuilder]
# gem "jbuilder"
# Use Redis adapter to run Action Cable in production
# gem "redis", "~> 4.0"
# Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis]
# gem "kredis"
# Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword]
# gem "bcrypt", "~> 3.1.7"
gem "jbuilder"
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem "tzinfo-data", platforms: %i[ mingw mswin x64_mingw jruby ]
@ -30,11 +21,10 @@ gem "tzinfo-data", platforms: %i[ mingw mswin x64_mingw jruby ]
# Reduces boot times through caching; required in config/boot.rb
gem "bootsnap", require: false
# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images]
# gem "image_processing", "~> 1.2"
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
# gem "rack-cors"
# From Neo4J.rb documentation
gem 'activegraph', '~> 11.3'
gem 'neo4j-ruby-driver', '~> 4.4.3'
gem 'neo4j-rake_tasks'
group :development, :test do
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem

View File

@ -46,6 +46,13 @@ GEM
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
activegraph (11.3.1)
activemodel (>= 4.0)
activesupport (>= 4.0)
i18n (!= 1.8.8)
neo4j-ruby-driver (>= 4.4.1)
orm_adapter (~> 0.5.0)
sorted_set
activejob (7.0.4.3)
activesupport (= 7.0.4.3)
globalid (>= 0.3.6)
@ -66,23 +73,37 @@ GEM
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
async (2.5.1)
console (~> 1.10)
io-event (~> 1.1)
timers (~> 4.1)
async-io (1.34.3)
async
bootsnap (1.16.0)
msgpack (~> 1.2)
builder (3.2.4)
concurrent-ruby (1.2.2)
connection_pool (2.4.1)
console (1.16.2)
fiber-local
crass (1.0.6)
date (3.3.3)
debug (1.8.0)
irb (>= 1.5.0)
reline (>= 0.3.1)
erubi (1.12.0)
fiber-local (1.0.0)
globalid (1.1.0)
activesupport (>= 5.0)
i18n (1.13.0)
concurrent-ruby (~> 1.0)
io-console (0.6.0)
io-event (1.2.2)
irb (1.6.4)
reline (>= 0.3.0)
jbuilder (2.11.5)
actionview (>= 5.0.0)
activesupport (>= 5.0.0)
loofah (2.21.3)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
@ -96,6 +117,16 @@ GEM
mini_mime (1.1.2)
minitest (5.18.0)
msgpack (1.7.1)
neo4j-rake_tasks (0.7.19)
os
rake
ruby-progressbar
rubyzip (>= 1.1.7)
neo4j-ruby-driver (4.4.4)
activesupport
async-io
connection_pool
zeitwerk (>= 2.1.10)
net-imap (0.3.4)
date
net-protocol
@ -106,8 +137,14 @@ GEM
net-smtp (0.3.3)
net-protocol
nio4r (2.5.9)
nokogiri (1.15.1-aarch64-linux)
racc (~> 1.4)
nokogiri (1.15.1-arm64-darwin)
racc (~> 1.4)
nokogiri (1.15.1-x86_64-linux)
racc (~> 1.4)
orm_adapter (0.5.0)
os (1.1.4)
puma (5.6.5)
nio4r (~> 2.0)
racc (1.6.2)
@ -141,11 +178,21 @@ GEM
thor (~> 1.0)
zeitwerk (~> 2.5)
rake (13.0.6)
rbtree (0.4.6)
reline (0.3.4)
io-console (~> 0.5)
ruby-progressbar (1.13.0)
rubyzip (2.3.2)
set (1.0.3)
sorted_set (1.0.3)
rbtree
set (~> 1.0)
sqlite3 (1.6.3-aarch64-linux)
sqlite3 (1.6.3-arm64-darwin)
sqlite3 (1.6.3-x86_64-linux)
thor (1.2.2)
timeout (0.3.2)
timers (4.3.5)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
websocket-driver (0.7.5)
@ -154,11 +201,17 @@ GEM
zeitwerk (2.6.8)
PLATFORMS
aarch64-linux
arm64-darwin-22
x86_64-linux
DEPENDENCIES
activegraph (~> 11.3)
bootsnap
debug
jbuilder
neo4j-rake_tasks
neo4j-ruby-driver (~> 4.4.3)
puma (~> 5.0)
rails (~> 7.0.4, >= 7.0.4.3)
sqlite3 (~> 1.4)

View File

@ -1,26 +1,38 @@
class MetricsController < ActionController::API
# GET /metric
def index
render json: {}
end
# POST /metric/:key
def create
key = params[:key]
value = JSON.parse(request.body.read)["value"]
metric = Metric.find_or_create_by(key: key)
metric.value = value
if metric.save()
render json: {}
else
render json: { error: "Unable to save" }, status: :unprocessable_entity
end
end
# GET /metric/:key
def show
# Return an empty JSON response
render json: {}
# GET /metric/
def index
returnable = []
Metric.all.each do |metric|
returnable << MetricOutput.new(metric.key, metric.value)
end
render json: returnable.to_json
end
# DELETE /metric/:key
def delete
key = params[:key]
metric = Metric.find_by(key: key)
if metric.destroy
render json: {}
else
render json: { error: "Unable to delete" }, status: :unprocessable_entity
end
end
end

View File

@ -0,0 +1,10 @@
class MetricOutput
attr_reader :key, :value
def initialize(key, value)
@key = key
@value = value
end
end

7
app/models/metric.rb Normal file
View File

@ -0,0 +1,7 @@
class Metric
include ActiveGraph::Node
property :key, type: String
property :value, type: Integer, default: 0
validates :key, :presence => true
end

View File

@ -1,6 +1,7 @@
require_relative "boot"
require "rails/all"
require 'active_graph/railtie'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
@ -10,7 +11,7 @@ module GrilloTest
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 7.0
config.generators { |g| g.orm :active_graph }
# Configuration for the application, engines, and railties goes here.
#
# These settings can be overridden in specific environments using the files

View File

@ -0,0 +1,11 @@
class CreateMetric < ActiveGraph::Migrations::Base
disable_transactions!
def up
add_constraint :Metric, :uuid
end
def down
drop_constraint :Metric, :uuid
end
end

21
db/neo4j/schema.yml Normal file
View File

@ -0,0 +1,21 @@
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Node to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.yml definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using neo4j:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended that you check this file into your version control system.
---
:constraints:
- 'CREATE CONSTRAINT `constraint_3d18f4d7` FOR (n:`Metric`) REQUIRE (n.`uuid`) IS
UNIQUE OPTIONS {indexConfig: {}, indexProvider: ''range-1.0''}'
- 'CREATE CONSTRAINT `constraint_dbcee0a4` FOR (n:`ActiveGraph::Migrations::SchemaMigration`)
REQUIRE (n.`migration_id`) IS UNIQUE OPTIONS {indexConfig: {}, indexProvider: ''range-1.0''}'
:indexes: []
:versions:
- '20230524023145'

View File

@ -9,5 +9,23 @@ services:
- "3000:3000"
volumes:
- "./:/app"
depends_on:
- neo4j
environment:
- NEO4J_URL=bolt://neo4j:7687
- ENVIRONMENT=development
platform: linux/amd64
neo4j:
image: neo4j
ports:
- "7474:7474"
- "7687:7687"
volumes:
- ./neo4j:/data
- ./neo4j/logs:/logs
environment:
- NEO4J_AUTH=none
#- dbms.connector.bolt.listen_address=:7687
#- dbms.connector.bolt.advertised_address=:7687

18
justfile Normal file
View File

@ -0,0 +1,18 @@
build:
docker compose build
run:
docker compose up
shell:
docker compose run app bash
migrate:
docker compose run app rails neo4j:migrate
clean-db:
rm -rf neo4j
clean:
rm -rf tmp/pids/server.pid

11
test/fixtures/metrics.yml vendored Normal file
View File

@ -0,0 +1,11 @@
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
# This model initially had no columns defined. If you add columns to the
# model remove the "{}" from the fixture names and add the columns immediately
# below each fixture, per the syntax in the comments below
#
one: {}
# column: value
#
two: {}
# column: value

View File

@ -0,0 +1,7 @@
require "test_helper"
class MetricTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end