Domanda

I have a mysql schema full of information that I'd like to expose with a RESTful API, preferably in Ruby.

What I know so far

  • "RESTful" refers to following a certain standard for your API, and is not associated with any particular implementation language.
  • I can use the mysql gem in Ruby to pull the data that I need from my database
  • The Sinatra project appears to be an easy way to set up an API using Ruby

An Example

Let's say I have a server (12.34.56.78) and my ruby code on that server is located at

/opt/example_code/main.rb. 

I'd like the user to be able to query something like

12.34.56.77/customers/1234?show_ssn=true

in order to retrieve a record for customer 1234, opting to also show the SSN

What I don't understand

  1. What basic server-side software do I need running to make this happen? I assume I need some sort of web server like Apache or nginx that's always running? I know you can run a simple HTTP server in python (python -m SimpleHTTPServer) which runs as long as my terminal window is open (or I cancel it). Are Apache and nginx similar to that but they run constantly as a process?

  2. When a user hits 12.34.56.77, how can I let the server know it should be looking in /opt/example_code for my script? Is there some sort of configuration I can set?

    I have a vague idea of how HTTP ports work; should I set certain ports to "point to" certain directories? For example, only if they specify port 5678 will the server know to correctly look in my /opt/example_code directory

    12.34.56.77:5678/customers/1234?show_ssn=true
    
  3. When the HTTP server finally deciphers the request and redirects it to /opt/example_code, what happens next? How do I instruct it to run my main.rb file in that directory? Also, how is the URI ("/customers...true") passed to my ruby app to be deciphered by Sinatra?

I think I have a grasp of the individual pieces that make this process, but I'm struggling on how they all integrate together.

Thanks for the help!

È stato utile?

Soluzione

  1. You need to run a web server (Apache or Nginx). Every request goes through the web server. If it is a request for static page, some asset, etc., web server will take care of it. If the request needs processing, it will be dispatched to the application server (thin, puma, unicorn...). Now, Apache or Nginx will be demonized, that means the process will run in the backround and not in the terminal. Same applies for your application server. You can find plenty of tutorials on line. Also be sure to check the docs.

  2. Well that really depends on your server. Both Apache and Nginx have it's own way of doing this. E.g., by editing sites-enabled file for Nginx. But again pick one and check it's docs, you will find everything there.

    About ports: No, you should not. The server will know where to look for your application because of it's configuration. Ports will allow you to run more servers or processes. Imagine, that your application server is running on port 3000. Nothing else can use that port anymore. This means, that if you want to run, for example, MySQL server on the same machine, it needs to use different port.

  3. You will configure your web server, so it knows where to look for bootstraping file. The routes like /customers will be declared in your sinatra app. Take a look on this http://recipes.sinatrarb.com/p/deployment/nginx_proxied_to_unicorn.

Please take in to account, that running an application in production without deep knowledge of server administration can be quite dangerous. Many things could go wrong. Maybe a good solution would be to use some cloud based service (Heroku, RackSpace...)?

I did something very similar. I wrote my API in Grape (https://github.com/intridea/grape), which is very similar to sinatra, but it is specifically design to build APIs. I'm useing Nginx as my webserver and Puma (https://github.com/puma/puma) as my application server.

Good luck!

Example for Nginx configuration (two services on same server)

/path/to/nginx/conf/sites-enabled/site1.com (using nginx with passenger):

server {
  listen 80;
  server_name site1.com;
}

server {
  listen 443;
  server_name site1.com;
  root /path/to/application/public-folder;
  passenger_enabled on;
}

/path/to/nginx/conf/sites-enabled/site2.com (using nginx with unicorn and some advanced configuration):

server {
  listen 80;
  server_name site2.com;
}

server {
  listen 443;
  server_name site2.com;
  root /path/to/application/public-folder;

  client_max_body_size       10m;
  client_body_buffer_size    128k;

  proxy_connect_timeout      90;
  proxy_send_timeout         90;
  proxy_read_timeout         90;

  proxy_buffer_size          4k;
  proxy_buffers              4 32k;
  proxy_busy_buffers_size    64k;
  proxy_temp_file_write_size 64k;


  location / {
    proxy_set_header   Host $http_host;
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Proto $scheme;
    proxy_redirect off;

    proxy_pass http://unicorn_cluster;
  }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top