How to get the parameters of url in Crystal lang - url

I'm learning Crystal lang for web development. I don't understand at all how to get the parameters that i send in a url. In PHP it is just $_GET[param] but all i find in crystal documentation is how to get the elements from the url but not how to get this url. I spent many hours in this but don't understand at all. Does anyone know how to do ? I'm sure it is not difficult but i don't find ! Thank you

If you are using default http server then you can acccess it using query_param
like this -
server = HTTP::Server.new do |context|
context.request.query_params.each do |name, value|
puts "query key is #{name} & value is #{value}"
end
end
but if you want to use it in a simple way - you can use some framework like shivneri
Here is how to do it in shivneri
class UserController < Shivneri::Controller
#[Worker]
def add_user
user_id = query["userid"]?
return text_result("ok")
end
end
For more info about - query string in shivneri framework, please visit - https://shivneriforcrystal.com/tutorial/query/

Related

How to find the request type?

I want to use a conditional to run a statement based on the type of request, but there is no way I can reproduce the error in production to see what the request is, but I was thinking of doing it this way:
def save_path
if request.method == 'GET'
# don't save the timeout path or else the user has no obvious way to log in
session[:desired_path] = request.url unless request.url =~ /#{timeout_path}$/
end
end
So, basically I want to say if the request's method is a GET request then this line should run but don't know if my conditional is setup correctly or not. Any assistance on this will be greatly appreciated.
You can check using a built in method:
request.get?
This answer to a similar question may be helpful for further info:
https://stackoverflow.com/a/4023538/3435610

Rails Gateway endpoints loaded from yml/env file

I have been trying to implement the Rails API Gateway concept and I have been struggling with a way to define routes without too much of a hustle.
My current implementation looks something like this:
module ServicesEndpoints
class StackOverflow
def self.check_comment(id)
begin
RestClient.get endpoint + comment_path(id)
rescue => e
#if the server is not up or errors occur from our point of view there is no data about the driver
raise my_error
end
end
private
def self.endpoint
ENV['STACKOVERFLOW_SERVICE_ADDRESS']
end
def self.comment_path(id)
"/comments/#{id}"
end
end
end
However this means that everytime i have to add an endpoint i need 1 class and for every route 1 action. Thinking about this I was wondering if you couldn't do this in an yml/.env file and just load them. However even if I know how to put the endpoint in the .env file routes with params are a little tricky(I have no good idea on how to do it).
Has someone tackled this problem and if so how did you go about to solve it?

Rails API and Strong PARAMS

I am trying to create an api to create record Foo using the rails-api gem.
I initially ran the generator command to tell rails to create a controller for me and it created this:
def create
#foo = Foo.new(foo_params)
#foo.save
respond_with(#foo)
end
And this (Strong params):
def foo_params
params.require(:foo).permit(:bar)
end
This is pretty standard stuff and will work when using form_for to submit data to the create method.
In my case, I'm creating a stand-alone API web service that will only interact via external API calls.
So the issue that I'm experiencing, is I don't know how to post the :bar param via API. I tried posting a :bar param, but this leads to a 'param is missing or the value is empty: foo' error. I understand why this is happening, but I have no idea how to get around this...
Is there a better way to do this or should I provide the api param in a different way?
PS. Currently my api POST call looks like this:
http://localhost:3000/api/v1/foo.json?bar=test#mail.com
you cannot use the ?+argument at the end of the url for a POST HTTP request, it's only for a GET request.
You must use the data component of the HTTP call, that is not embedded in the URL
therefore, you cannot just make this from your browser address bar and must use curl or a great tool as Postman (free on the chrome App Store)
and in this data field, you can include the object you want to post (postman gives you a neat key value interface to do so)
let me know if you need more details on the curl function for command line calls, but I recommend that you use a nice tool as Postman, so useful if you're not used to these calls
EDIT : this is the URL to get Postman : https://www.getpostman.com

Rails condition based on URL

Hi im working on a Rails app, i didnt write the whole app, there is a part where i need to Echo a meesage if the user is Elite.. i know that in the URL i have the info
sign_up?locale=en&t=elite
Is there any chance i can use that in view to do something like you would do a GET condition pn PHP?
i mean if (t=elite) {echo this} else {}
Hope anyone can give me an easy solution for this, that not requiere wirte a hole method just for echoing 1 little message just for that kind of users.
thanks, also just as note im a noob on rails, but im doing just HTML/CSS integration
Query parameters are available in the params Hash on each request:
<% if "elite" == params[:t] %>Check it out<% end %>

Include params/request information in Rails logger?

I'm trying to get some more information into my Rails logs, specifically the requested URI or current params, if available (and I appreciate that they won't always be). However I just don't seem able to. Here's what I've done so far:
#config/environments/production.rb
config.logger = Logger.new(config.log_path)
config.log_level = :error
config.logger.level = Logger::ERROR
#config/environment.rb
class Logger
def format_message(level, time, progname, msg)
"**********************************************************************\n#{level} #{time.to_s(:db)} -- #{msg}\n"
end
end
So I can customize the message fine, yet I don't seem to be able to access the params/request variables here. Does anyone know if this is possible, and if so how? Or if there's a better way to get this information? (Perhaps even something Redis based?)
Thanks loads,
Dan
(Responding a long time after this was asked, but maybe it will help the next person.)
I just did something similar.
1) you need to override your logger separately from logging request-leve details. Looks like you've figured customizing your logger out. Answer is here:
Rails logger format string configuration
2) I log the request and response of all requests into my service. Note, that Rails puts a tonne of stuff into the headers, so just straight dumping the request or the headers is probably a bad idea. Also of note, my application is primarily accessed via an API. If yours is primarily a web-app, as I'm guessing most people's are, you probably don't want to inspect the response.body as it will contain your html.
class ApplicationController < ActionController::Base
around_filter :global_request_logging
...
def global_request_logging
http_request_header_keys = request.headers.keys.select{|header_name| header_name.match("^HTTP.*")}
http_request_headers = request.headers.select{|header_name, header_value| http_request_header_keys.index(header_name)}
logger.info "Received #{request.method.inspect} to #{request.url.inspect} from #{request.remote_ip.inspect}. Processing with headers #{http_request_headers.inspect} and params #{params.inspect}"
begin
yield
ensure
logger.info "Responding with #{response.status.inspect} => #{response.body.inspect}"
end
end
end
This should work! :) cheers.
logger.info({:user_agent =>
request.user_agent, :remote_ip =>
request.remote_ip}.inspect)
logger.info(params.inspect)
By the by.. This should be placed in your controllers action. Ex: If you place it in your create action it should also log the user_agent i.e the browser, remote_ip i.e the remote ip of the user and all the params.
you should look in the request class
like puts request.uri.
check here for more detail http://api.rubyonrails.org/classes/ActionController/AbstractRequest.html

Resources