{"id":21192154,"url":"https://github.com/mu-semtech/mu-ruby-template","last_synced_at":"2025-08-25T19:03:28.002Z","repository":{"id":45938625,"uuid":"49282880","full_name":"mu-semtech/mu-ruby-template","owner":"mu-semtech","description":"Template for running Ruby/Sinatra microservices","archived":false,"fork":false,"pushed_at":"2025-07-23T08:54:19.000Z","size":132,"stargazers_count":3,"open_issues_count":1,"forks_count":10,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-07-23T10:36:04.707Z","etag":null,"topics":["mu-template","musemtech","ruby","sinatra"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mu-semtech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-01-08T16:24:47.000Z","updated_at":"2025-07-06T12:24:49.000Z","dependencies_parsed_at":"2025-07-03T14:23:57.529Z","dependency_job_id":"d814f314-6fac-4cb1-b871-3aef841416ca","html_url":"https://github.com/mu-semtech/mu-ruby-template","commit_stats":null,"previous_names":[],"tags_count":29,"template":false,"template_full_name":null,"purl":"pkg:github/mu-semtech/mu-ruby-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mu-semtech%2Fmu-ruby-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mu-semtech%2Fmu-ruby-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mu-semtech%2Fmu-ruby-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mu-semtech%2Fmu-ruby-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mu-semtech","download_url":"https://codeload.github.com/mu-semtech/mu-ruby-template/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mu-semtech%2Fmu-ruby-template/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272116855,"owners_count":24876268,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-25T02:00:12.092Z","response_time":1107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["mu-template","musemtech","ruby","sinatra"],"created_at":"2024-11-20T19:07:44.718Z","updated_at":"2025-08-25T19:03:27.979Z","avatar_url":"https://github.com/mu-semtech.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Mu Ruby template\nTemplate for writing semantic.works services in Ruby using [Sinatra](http://www.sinatrarb.com/)\n\n## Tutorials\n### Develop your first microservice\nRequires: a semantic.works stack, like mu-project.\n\nCreate a new folder for your microservice.\n\nIn the folder, create your microservice in `web.rb`:\n\n```ruby\nget '/hello' do\n  status 200\n  {\n    message: \"Hello mu-ruby-template\"\n  }.to_json\nend\n```\n\nThis service will respond with 'Hello mu-ruby-template' when receiving a GET request on '/hello'.\n\nAdd the mu-ruby-template to your `docker-compose.yml` with the sources mounted directly.\n\n```yml\nservices:\n    your-microservice-name:\n      image: semtech/mu-ruby-template:3.1.0\n      environment:\n        RACK_ENV: \"development\"\n      ports:\n        - 8888:80\n      volumes:\n        - /absolute/path/to/your/sources/:/app/\n```\n\nNext, create the service by running\n```\ndocker-compose up -d your-microservice-name\n```\n\nA `curl` call to the microservice will show you to message\n\n```bash\ncurl http://localhost:8888/hello\n# Hello mu-ruby-template\n```\n\n## How-to\n### Develop in a mu.semte.ch stack\nRequires:\n- a semantic.works stack, like mu-project\n- 'Develop your first microservice'\n\nWhen developing inside an existing mu.semte.ch stack, it is easiest to set the development mode by setting the `RACK_ENV` environment variable to `development` and mount the sources directly.  This makes it easy to setup links to the database and the dispatcher. Livereload is enabled automatically when running in development mode.\n\n```yml\nservices:\n  ...\n  your-microservice-name:\n    image: semtech/mu-ruby-template:3.1.0\n    environment:\n      RACK_ENV: \"development\"\n    volumes:\n      - /absolute/path/to/your/sources/:/app/\n```\n\n### Build a microservice based on mu-ruby-template\nRequires:\n- a semantic.works stack, like mu-project\n- 'Develop your first microservice'\n\nAdd a Dockerfile with the following contents:\n\n```docker\nFROM semtech/mu-ruby-template:3.1.0\nLABEL maintainer=\"john.doe@example.com\"\n```\n\nThere are various ways to build a Docker image. For a production service we advise to setup automatic builds, but here we will build it locally. You can choose any name, but we will call ours 'say-hello-service'.\n\nFrom the root of your microservice folder execute the following command:\n```bash\ndocker build -t say-hello-service .\n```\n\nAdd the newly built service to your application stack in `docker-compose.yml`\n```yml\nservices:\n  ...\n  say-hello:\n    image: say-hello-service\n```\n\nLaunch the new container in your app\n```bash\ndocker-compose up -d say-hello\n```\n\n### Debug your microservice\nRequires: 'Develop in a mu.semte.ch stack'.\n\nIf desired, [debug](https://rubygems.org/gems/debug) and [Better Errors](https://rubygems.org/gems/better_errors) can be used during development, giving advanced ruby debugging features.\n\n#### Inspecting errors after the fact\nRequires: 'Access your microservice directly'.\n\nWhen an error occurs, an interactive [Better Errors](https://github.com/charliesome/better_errors) error page is available at `http://localhost:8888/__better_errors`.\n\n#### Attach the Chrome debugger\nWhen running in development mode, you can attach the debugger to your microservice and add breakpoints as you're used to. The debugger requires port 9229 to be forwarded, and your service to run in development mode.\n\n```yml\nmy-ruby-service:\n  image: semtech/mu-ruby-template:3.1.0\n  ports:\n    - 9229:9229\n  environment:\n    RACK_ENV: \"development\"\n  volumes:\n    - /absolute/path/to/your/sources/:/app/\n```\n\nAdd a breakpoint in your code by inserting a `binding.break` (alias `debugger`, `binding.b`) statement.\n\nAfter launching your service, open Google Chrome or Chromium and visit [chrome://inspect](chrome://inspect). Once you reach the breakpoint, the file containing your code will be automatically opened in the 'Sources' tab.\n\n### Access your microservice directly\nRequires: 'Build a microservice based on mu-ruby-template' or 'Develop in a mu.semte.ch stack'\n\nIf you doubt your requests are arriving at your microservice correctly, you can publish it port to access it directly. In the example below, port 8888 is used to access the service directly.\n\nNote this means you will not have the headers set by the identifier and dispatcher.\n\nUpdate your service definition in `docker-compose.yml` as follows:\n\n```yml\n    your-microservice-name:\n      ...\n      ports:\n        - 8888:80\n```\n\nNext, recreate the container by executing\n```bash\ndocker-compose up -d your-microservice-name\n```\n\n### Add a dependency to your microservice\nYou can install additional dependencies by including a `Gemfile` file next to your `web.rb`. It works as you would expect: just specify the dependencies in the `Gemfile`. They will be installed automatically at build time. In development mode you will need to restart the container.\n\n\n### Execute a SPARQL query\nThe template provides several helpers. One of them, `Mu::query`, allows to easily execute a SPARQL query as shown in the following example:\n\n```ruby\nget '/triples' do\n  solutions = Mu::query(\"SELECT * WHERE { ?s ?p ?o }\")\n  triples = solutions.map do |solution|\n    {\n      subject: solution[:s],\n      predicate: solution[:p],\n      object: solution[:o]\n    }\n  end\n  status 200\n  {\n    data: triples\n  }.to_json\nend\n```\n\n### Include utils as globals\nThe utils can be included as global functions by including the `Mu` module. This makes the code somewhat shorter but may cause conflicts with other libraries in the global namespace.\n\nFor example `Mu::query` can then be written as `query`:\n\n```ruby\ninclude Mu\n\nget '/triples' do\n  solutions = query(\"SELECT * WHERE { ?s ?p ?o }\")\n  ...\nend\n```\n\n### How to run tests\nTo test your app, run the container with `RACK_ENV` set to `test`. All [rspec](http://rspec.info/) tests matching `*_spec.rb` in `spec/` and its subdirectories will be executed.\n\n    docker run --rm -e RACK_ENV=test microservice-image\n\nTo run the tests while developing, start an interactive container in the test enviroment  with your code folder mounted in `/app`:\n\n    docker run --volume /path/to/your/code:/app\n                -e RACK_ENV=test\n                -it semtech/mu-ruby-template:3.1.0 /bin/bash\n\nYou can now run your tests inside the container with:\n\n    bundle install\n    rspec\n\n## Reference\n### Framework\nThe mu-ruby-template is built on Sinatra. Check [Sinatra's Getting Started guide](https://sinatrarb.com/intro.html) to learn how to build a REST API in Sinatra.\n\n### Utils\nThe template offers a `Mu` module with utils to facilitate development.\n\n#### Mu::graph\nReturns the application graph configured through the `MU_APPLICATION_GRAPH`.\n\n#### Mu::generate_uuid()\nGenerate a random UUID (String).\n\n#### Mu::log\nThe template provides a [Logger](https://ruby-doc.org/stdlib-2.3.0/libdoc/logger/rdoc/Logger.html) `log` object to the user for logging. Just do `Mu::log.info \"Hello world\"`. The log level can be set through the `LOG_LEVEL` environment variable (default: `info`, values: `debug`, `info`, `warn`, `error`, `fatal`).\n\nLogs are written to the `/logs` directory and `STDOUT` in the docker container.\n\n#### Mu::query(query, **options)\nExecutes the given SPARQL select/ask/construct query. Options is an object which may include `sudo` and `scope` keys.\n\n#### Mu::sparql_client\nReturns a SPARQL::Client instance connection to the SPARQL endpoint configured through the `MU_SPARQL_ENDPOINT` environment variable.\n\n#### *.sparql_escape ; Mu::sparql_escape_{string|uri|date|datetime|bool|int|float}(value)\nThe Ruby templates extends the core classes `String`, `Date`, `DateTime`, `Time`, `Integer`, `Float`, `Boolean` and `URI` with a `sparql_escape` method. This method can be used to avoid SPARQL injection by escaping user input while constructing a SPARQL query. E.g.\n\n```ruby\nquery =  \" INSERT DATA {\"\nquery += \"   GRAPH \u003c#{Mu::graph}\u003e {\"\nquery += \"     #{Mu::sparql_escape_uri(user_uri)} a \u003c#{RDF::Vocab::FOAF.Person}\u003e ;\"\nquery += \"                   \u003c#{RDF::Vocab::FOAF.name}\u003e #{name.sparql_escape} ;\"\nquery += \"                   \u003c#{RDF::Vocab::DC.created}\u003e #{now.sparql_escape} .\"\nquery += \"   }\"\nquery += \" }\"\n```\n\nNext to the extensions, the template also provides a helper function per datatype that takes any value as parameter. E.g. `Mu::sparql_escape_uri(\"http://mu.semte.ch/application\")`.\n\n#### Mu::update(query, **options)\nExecutes the given SPARQL update query. Options is an object which may include `sudo` and `scope` keys.\n\n#### Mu::update_modified(subject, modified = DateTime.now)\nExecutes a SPARQL query to update the modification date of the given subject URI (string). The date defaults to now.\n\n\n### Sinatra helpers\nThe template provides the following Sinatra helpers which can only be used in a route-handling context:\n\n#### @json_body\nThe parsed JSON body of the request.\n\n#### error(title, status = 400)\nReturns a JSONAPI compliant error response with the given status code (default: `400`).\n\n#### rewrite_url_header(request)\nGet the rewrite URL from the request headers.\n\n#### session_id_header(request)\nGet the session id from the request headers.\n\n#### validate_json_api_content_type(request)\nValidate whether the Content-Type header contains the JSONAPI Content-Type. Returns a `400` otherwise.\n\n#### validate_resource_type(expected_type, data)\nValidate whether the type specified in the JSON data is equal to the expected type. Returns a `409` otherwise.\n\n### Debugger\n[ruby/debug](https://github.com/ruby/debug) supports multiple frontends for remote debugging of which we advise the Chromium inspector. You can configure the frontend via `RUBY_DEBUG_OPEN_FRONTEND` environment variable. Other options are untested.\n\n### Environment variables\nThe template supports the following environment variables:\n\n- `MU_SPARQL_ENDPOINT`: SPARQL endpoint URL. Default: `http://database:8890/sparql`\n- `MU_SPARQL_TIMEOUT`: timeout (in seconds) for SPARQL queries. Default: 60 seconds.\n- `ALLOW_MU_AUTH_SUDO`: Allow sudo queries when the service requests it.\n- `DEFAULT_MU_AUTH_SCOPE`: Default mu-auth-scope to use for calls.\n- `LOG_LEVEL`: the level of logging (default: `info`, values: `debug`, `info`, `warn`, `error`, `fatal`).\n- `USE_LEGACY_UTILS`: when enabled (using `\"true\"` or `\"yes\"`) legacy utils from v2 will be included in the root file so they can be used as before (e.g. `query` instead of `Mu::query`). Default: `\"true\"`\n- `PRINT_DEPRECATION_WARNINGS`: Deprecation warnings will be printed for each usage of a legacy util. Default: `\"true\"`.\n- `RACK_ENV`: environment to start the Sinatra application in. Default: `production`. Possible values `production`, `development`, `test`.\n- `RUBY_DEBUG_PORT`: port to use for remote debugging. Default: `9229`.\n- `RUBY_DEBUG_OPEN_FRONTEND`: frontend to use for debugging. Default: `chrome`. Other options are untested.\n- `RUBY_OPTIONS`: options to pass to the ruby command on startup. Default: `--jit`.\n\n### Custom build commands\nTo execute custom bash statements during the image build (e.g. to install aditional system libraries), provide an `on-build.sh` script in the root of your service. It will be automatically picked up and executed by the Docker build.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmu-semtech%2Fmu-ruby-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmu-semtech%2Fmu-ruby-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmu-semtech%2Fmu-ruby-template/lists"}