작업은 1. 프로젝트 생성 -> 2. 라우트 설정 -> 3. 컴포넌트 생성 -> 4. 컨트롤러 작성 -> 5. 뷰 작성 등으로 진행됩니다.
1. C9 프로젝트 생성
1.1 C9 로그인 후 Workspaces 에서 Create a new workspace 를 선택합니다.
1.2 Workspace 정보 입력 후 Ruby on Rails 템플릿을 선택합니다.
1.3 C9 프로젝트 생성 완료 화면입니다.
2. 환경설정
라우트에 주소규칙을 설정할 수 있습니다. config/routes.rb 파일에 아래를 참고하여 주소규칙을 작성해봅니다.
Rails.application.routes.draw do
# get "/" => "<<컨트롤러>>#<<액션명>>" # "/" 로 접속시 <<컨트롤러>>의 <<액션명>> 실행
# get "/" => "member#login" # "/" 로 접속시 member 컨트롤러의 login 액션 실행
get "/member/login" => "member#login" # "/" 로 접속시 member 컨트롤러의 login 액션 실행
end
3. 컴포넌트 생성
Cloud9 bash 창에서 아래 커맨드로 컴포넌트 생성할 수 있습니다.
rails generate controller <<컴포넌트명>> #<<컴포넌트명>> 컴포넌트 생성
rails g controller <<컴포넌트명>> # 위와 동일
rails g controller Member # Memeber 컴포넌트 생성
실제 컴포넌트 생성 결과입니다.
$ rails g controller Member # Memeber 컴포넌트 생성
Running via Spring preloader in process 2371
create app/controllers/member_controller.rb # 컨트롤러
invoke erb
create app/views/member # 뷰 경로
invoke test_unit
create test/controllers/member_controller_test.rb # 컨트롤러 테스트
invoke helper
create app/helpers/member_helper.rb # 헬퍼
invoke test_unit
invoke assets
invoke coffee
create app/assets/javascripts/member.coffee #자바스크립트
invoke scss
create app/assets/stylesheets/member.scss # 스타일시트
4. 컨트롤러 작성
config/routes.rb 에 작성하였던 컨트롤러에 액션을 추가해 보겠습니다.
app/controllers/member_controller.rb 에 아래과 같이 작성해 봅니다.
class MemberController < ApplicationController
def login
end
end
5. 뷰 작성
이제 컨트롤러의 액션에 해당하는 뷰를 작성해 보겠습니다.
app/views/member/login.html.erb파일을 생성 후 아래와 같이 작성해 봅니다. (파일명을 액션명과 맞춰줘야 합니다.)
<h1>Log In@@@</h1>
6. 결과 보기 및 다양한 출력 방법
지금까지 프로젝트 생성 후 라우트 설정을 하였고, 컴포넌트를 생성하여 컨트롤러와 뷰를 작성하였습니다.
이제 그 결과를 확인해 볼 차례입니다.
아래 C9 Workspace에서 Run Project 를 통해 서버를 구동시켜봅니다.
그리고 서버 구동 후 아래 링크들을 열어 결과를 확인해 볼 수 있습니다.
6.1 그 결과는 아래와 같습니다.
6.2 이번에는 컨트롤러에서 직접 내용을 출력해보겠습니다.
app/controllers/member_controller.rb 에 아래과 같이 작성해 봅니다.
class MemberController < ApplicationController
def login
render text: "Log In!!!" # 뷰에서 "Log In!!!" 문구 출력
end
end
그 결과를 확인해봅니다.
6.3 이번에는 뷰 파일명을 달리하여 컨트롤러 액션에서 직접 지정하여 출력해보겠습니다.
app/views/member/test_login.html.erb 파일을 생성 후 아래와 같이 작성해 봅니다.
<h1>Log In Test@@@</h1>
그리고 app/controllers/member_controller.rb 에 아래과 같이 작성해 봅니다.
class MemberController < ApplicationController
def login
render "test_login" # test_login 뷰 지정
end
end
그 결과를 확인해봅니다.
이렇게 Cloud9 과 Ruby on Rails를 통해 간단하게 페이지를 작성해 보았습니다.
FROM ubuntu
ENV PATH "~/.rbenv/bin:$PATH"
ENV PATH "~/.rbenv/versions/2.3.0/bin:$PATH"
ENV RAILS_ENV development
EXPOSE 3000
# Run upgrades
RUN apt-get -y update
# Install basic packages
RUN apt-get -y install git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev python-software-properties libffi-dev
RUN apt-get install nano
#RUN cd
WORKDIR ~
RUN git clone git://github.com/sstephenson/rbenv.git ~/.rbenv
RUN git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
RUN ls ~/.rbenv
RUN ~/.rbenv/bin/rbenv init -
# 루비 설치
RUN ~/.rbenv/bin/rbenv install -v 2.3.0
RUN ~/.rbenv/bin/rbenv global 2.3.0
RUN ~/.rbenv/versions/2.3.0/bin/ruby -v
# gem 설정, bundler 설치
RUN echo "gem: --no-document" > ~/.gemrc
RUN ~/.rbenv/versions/2.3.0/bin/gem install bundler
# 레일즈 설치
RUN ~/.rbenv/versions/2.3.0/bin/gem install rails -v 4.2.5
RUN ~/.rbenv/bin/rbenv rehash
RUN ~/.rbenv/versions/2.3.0/bin/rails -v
# node js 설치
RUN apt-get -y install nodejs
# 프로젝트 소스 clone
WORKDIR /app
RUN git clone https://id:pwd@bitbucket.org/<<아이디>>/<<프로젝트>>
# bunde install
WORKDIR /app/testror
RUN ~/.rbenv/versions/2.3.0/bin/bundle install
RUN ~/.rbenv/versions/2.3.0/bin/bundle exec rake db:migrate
# rails 서버 start
CMD ~/.rbenv/versions/2.3.0/bin/rails s -b 0.0.0.0 -p 3000
위 내용을 간단히 설명하자면 아래와 같습니다.
ubuntu 이미지 기반
환경변수 설정 후 3000포트 사용 정의
기본 패키지 업데이트 및 설치
ruby 설치
gem 설정, bundler 설치
rails 설치
node js 설치
Rails 어플리케이션 clone
bundle install 및 db migrate
CMD 명령으로 컨테이너 실행시마다 rails 서버 시작
2. Dockerfile 작성 후 Docker Image 빌드를 합니다.
Dockerfile이 있는 경로에서 아래 커맨드를 실행합니다.
docker build -t ror .
위 커맨드를 간단히 설명하자면 아래와 같습니다.
Docker Image를 build 하겠다.
-t로 이름과 태그 지정(name/tag식으로 tag 안 쓸 경우는 name만). 이름은 ror로 지정
. 으로 빌드 대상 경로 지정. Dockerfile 있는 경로로
완료 후 docker images 로 이미지 생성 완료 확인
실패시 docker rmi ≪image name≫ 으로 실패한 이미지 삭제
실행시 아래와 같은 결과를 확인할 수 있습니다.
$ docker build -t ror .
Sending build context to Docker daemon 16.38kB
Step 1/28 : FROM ubuntu
---> 20c44cd7596f
...
Successfully built 840df28a7759
Successfully tagged ror:latest
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ror latest 840df28a7759 2 hours ago 842MB
3. Docker Container를 생성 및 실행합니다.
Docker Image 생성 완료 후 아래 커맨드로 컨테이너를 생성 및 실행합니다.
docker run -d --name ror -p 60005:3000 ror
위 커맨드를 간단히 설명하자면 아래와 같습니다.
Docker Image를 build 하겠다.
Docker Container를 run 하겠다.
-d 옵션으로 컨테이너를 백그라운드에서 실행
--name 으로 컨테이너 이름 설정. ror로 설정함
-p 로 호스트에 연결된 컨테이너의 특정 포트를 외부에 노출(<호스트 포트>:<컨테이너 포트>)
ror 이미지로 생성
실패시 docker rm ror 로 컨테이너 삭제
실행시 아래와 같은 결과를 확인할 수 있습니다.
$ docker run -d --name ror -p 60005:3000 ror
0431b06b76a1978898d3f0cdf44ebda94.......
$ docker logs ror
[2017-12-28 10:40:46] INFO WEBrick 1.3.1
[2017-12-28 10:40:46] INFO ruby 2.3.0 (2015-12-25) [x86_64-linux]
[2017-12-28 10:40:46] INFO WEBrick::HTTPServer#start: pid=6 port=3000
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0431b06b76a1 ror "/bin/sh -c '~/.rb..." 2 hours ago Up 2 hours 0.0.0.0:60005->3000/tcp ror
위와 같이 하신 후 브라우저에서 locahost:60005 로 연결하시면 Ruby On Rails 프로젝트 동작을 확인할 수 있습니다.
참고로 위 작업을 마친 후 아래 링크도 찾게 되었네요;; 그런데 안해봐서 아래 링크대로는 아직 확인을 못해봤습니다.
public class BithumbTickerData {
@SerializedName("opening_price")
public String openingPrice;
@SerializedName("closing_price")
public String closingPrice;
@SerializedName("min_price")
public String minPrice;
@SerializedName("max_price")
public String maxPrice;
@SerializedName("average_price")
public String averagePrice;
@SerializedName("units_traded")
public String unitsTraded;
@SerializedName("volume_1day")
public String volume1day;
@SerializedName("volume_7day")
public String volume7day;
@SerializedName("buy_price")
public String buyPrice;
@SerializedName("sell_price")
public String sellPrice;
@SerializedName("date")
public long date;
}
public class BithumbTicker {
@SerializedName("status")
public String status;
@SerializedName("data")
public BithumbTickerData data;
}
4. interface 생성
API Method 방식 및 Path에 대해서 정의하자.
public interface OpenApiService {
@GET("public/ticker/{path}")
Call tickerInfo(@Path("path") String path);
}
5.1. Retrofit 초기화
Retrofit 생성 후 사용할 interface를 통해 서비스를 만들자. (Response를 String 형태로 받고 싶다면 ScalarsConverterFactory 사용)
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.bithumb.com/")
.addConverterFactory(GsonConverterFactory.create()) // Gson 처리시
//.addConverterFactory(ScalarsConverterFactory.create()) // String 등 처리시
.build();
OpenApiService openApiService = retrofit.create(OpenApiService.class);
기존과 비교했을 때 OkhttpClient 라는 놈을 Retrofit Builder에 추가하는 모습이 보인다.
개인적으로 디버그 모드일때만 로그를 보기 위해 BuildConfig.DEBUG 로 분기 처리를 하였다.
그리고 로그 수준은 아래와 같다.
public final class HttpLoggingInterceptor implements Interceptor {
...
public enum Level {
/** No logs. */
NONE,
/**
* Logs request and response lines.
*
*
Example:
*
{@code
* --> POST /greeting http/1.1 (3-byte body)
*
* <-- 200 OK (22ms, 6-byte body)
* }
*/
BASIC,
/**
* Logs request and response lines and their respective headers.
*
*
Example:
*
{@code
* --> POST /greeting http/1.1
* Host: example.com
* Content-Type: plain/text
* Content-Length: 3
* --> END POST
*
* <-- 200 OK (22ms)
* Content-Type: plain/text
* Content-Length: 6
* <-- END HTTP
* }
*/
HEADERS,
/**
* Logs request and response lines and their respective headers and bodies (if present).
*
*
Example:
*
{@code
* --> POST /greeting http/1.1
* Host: example.com
* Content-Type: plain/text
* Content-Length: 3
*
* Hi?
* --> END POST
*
* <-- 200 OK (22ms)
* Content-Type: plain/text
* Content-Length: 6
*
* Hello!
* <-- END HTTP
* }
*/
BODY
}
위 소스를 보면 로그 레벨은 NONE, BASIC, HEADERS, BODY 로 이루어져 있다. 필요에 따라 설정하면 된다.
- NONE : No logs.
- BASIC : Logs request and response lines.
- HEADERS : Logs request and response lines and their respective headers.
- BODY : Logs request and response lines and their respective headers and bodies (if present).
앱을 실제 signed release apk 만들시 Progaurd 사용하는데, 이때 Retrofit 사용시 아래와 같이 proguard.pro 파일에 추가해준다.
# Platform calls Class.forName on types which do not exist on Android to determine platform.
-dontnote retrofit2.Platform
# Platform used when running on Java 8 VMs. Will not be used at runtime.
-dontwarn retrofit2.Platform$Java8
# Retain generic type information for use by reflection by converters and adapters.
-keepattributes Signature
# Retain declared checked exceptions for use by a Proxy instance.
-keepattributes Exceptions
Retrofit 로그에서 문제가 될시 아래도 추가해 보자.
-dontwarn okhttp3.**
-dontwarn okio.**
-dontwarn javax.annotation.**
# A resource is loaded with a relative path so the package of this class must be preserved.
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase