diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index eef849d8209a5a61398383d9b456ed5344bf2855..ca85ba6b25758fa4adb02737dc7b5a67b205487f 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -59,9 +59,7 @@ class Projects::IssuesController < Projects::ApplicationController
   end
 
   def create
-    @issue = @project.issues.new(params[:issue])
-    @issue.author = current_user
-    @issue.save
+    @issue = Issues::CreateService.new(project, current_user, params[:issue]).execute
 
     respond_to do |format|
       format.html do
diff --git a/app/observers/issue_observer.rb b/app/observers/issue_observer.rb
index 30da1f83da796c7a79dfe16ee0447775ab52ec80..c2132ddca55dd3e6169ef904ca7c62148ae512ba 100644
--- a/app/observers/issue_observer.rb
+++ b/app/observers/issue_observer.rb
@@ -1,11 +1,4 @@
 class IssueObserver < BaseObserver
-  def after_create(issue)
-    notification.new_issue(issue, current_user)
-    event_service.open_issue(issue, current_user)
-    issue.create_cross_references!(issue.project, current_user)
-    execute_hooks(issue)
-  end
-
   def after_close(issue, transition)
     notification.close_issue(issue, current_user)
     event_service.close_issue(issue, current_user)
diff --git a/app/services/base_service.rb b/app/services/base_service.rb
index 610f04748722a7c729fba28e590531bc204f97f2..9ad8092315266ea094631f45134f486c3fbc42ec 100644
--- a/app/services/base_service.rb
+++ b/app/services/base_service.rb
@@ -16,4 +16,16 @@ class BaseService
   def can?(object, action, subject)
     abilities.allowed?(object, action, subject)
   end
+
+  def notification_service
+    NotificationService.new
+  end
+
+  def event_service
+    EventCreateService.new
+  end
+
+  def log_info message
+    Gitlab::AppLogger.info message
+  end
 end
diff --git a/app/services/issues/create_service.rb b/app/services/issues/create_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..37f440fc40e7c96e634f1fa7b58f7d3d0cae0208
--- /dev/null
+++ b/app/services/issues/create_service.rb
@@ -0,0 +1,23 @@
+module Issues
+  class CreateService < BaseService
+    def execute
+      issue = project.issues.new(params)
+      issue.author = current_user
+
+      if issue.save
+        notification_service.new_issue(issue, current_user)
+        event_service.open_issue(issue, current_user)
+        issue.create_cross_references!(issue.project, current_user)
+        execute_hooks(issue)
+      end
+
+      issue
+    end
+
+    private
+
+    def execute_hooks(issue)
+      issue.project.execute_hooks(issue.to_hook_data, :issue_hooks)
+    end
+  end
+end
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
index 3d15c35b8cc4db079fc3d193a6db37ae001a5be1..169c58b00751f9abe2f88f3047867517a56d371e 100644
--- a/lib/api/issues.rb
+++ b/lib/api/issues.rb
@@ -48,17 +48,15 @@ module API
       # Example Request:
       #   POST /projects/:id/issues
       post ":id/issues" do
-        set_current_user_for_thread do
-          required_attributes! [:title]
-          attrs = attributes_for_keys [:title, :description, :assignee_id, :milestone_id]
-          attrs[:label_list] = params[:labels] if params[:labels].present?
-          @issue = user_project.issues.new attrs
-          @issue.author = current_user
-          if @issue.save
-            present @issue, with: Entities::Issue
-          else
-            not_found!
-          end
+        required_attributes! [:title]
+        attrs = attributes_for_keys [:title, :description, :assignee_id, :milestone_id]
+        attrs[:label_list] = params[:labels] if params[:labels].present?
+        issue = ::Issues::CreateService.new(user_project, current_user, attrs).execute
+
+        if issue.valid?
+          present issue, with: Entities::Issue
+        else
+          not_found!
         end
       end
 
diff --git a/spec/services/issues/create_service_spec.rb b/spec/services/issues/create_service_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7e2d5ad2e81d8f0864bb95a1dd5819c8d31e7cdc
--- /dev/null
+++ b/spec/services/issues/create_service_spec.rb
@@ -0,0 +1,22 @@
+require 'spec_helper'
+
+describe Issues::CreateService do
+  let(:project) { create(:empty_project) }
+  let(:user) { create(:user) }
+
+  describe :execute do
+    context "valid params" do
+      before do
+        project.team << [user, :master]
+        opts = {
+          title: 'Awesome issue',
+          description: 'please fix'
+        }
+
+        @issue = Issues::CreateService.new(project, user, opts).execute
+      end
+
+      it { @issue.should be_valid }
+    end
+  end
+end