2013-12-05 3 views
0

мое приложение - менеджер книг, где я могу создавать книги и страницы.restFUL API зависимость от магазина

у меня BookController с «магазином» на POST, хранящее название и описание.

public function store() 
{ 


    $rules = array(
     'title'   => 'required|min:3', 
     'description' => 'required|min:30' 
    ); 


    $validator = Validator::make(Input::all(), $rules); 

    if ($validator->fails()) { 
     return Response::json(
      array(
       'metadata' => array(
        'error'  => true, 
        'message' => 'The book creation has failed' 
       ) 
      ), 
      400 
     ); 
    } 

    else { 

     $slug   = Str::slug(Request::get('title')); 
     $existSlug  = Book::where('slug',$slug)->get(); 

     if(count($existSlug) > 0) { 
      return Response::json(
       array(
        'metadata' => array(
         'error'  => true, 
         'message' => 'This title is already taken' 
        ) 
       ), 
       400 
      ); 
     } 
     else { 
      $book    = new Book; 
      $book->title  = Request::get('title'); 
      $book->slug   = $slug; 
      $book->description = Request::get('description'); 
      $book->user_id  = Auth::user()->id; 
      $book->status  = false; 
      $book->save(); 

      $stored = $book->toArray(); 
      $metadata = array(
       'metadata' => array(
        'error' => false, 
       ) 
      ); 
      return Response::json(
       array_merge($stored,$metadata), 
       201 
      ); 
     } 

    } 

} 

У меня также есть PageController с «магазином» на POST, хранящее содержание страницы:

public function store() 
{ 
    $rules = array(
     'content'  => 'required|between:300,350', 
     'book_id'  => 'required|exists:books,id' 
    ); 

    $validator = Validator::make(Input::all(), $rules); 

    if($validator->fails()) { 

     return Response::json(
      array(
       'metadata' => array(
        'error'  => true, 
        'message' => 'The page must be between 300 and 350 characters' 
       ) 

      ), 
      400 
     ); 
    } 
    else { 

     $book    = Book::find(Input::get('book_id')); 
     $content   = Input::get('content'); 
     $parent    = Page::where('book_id',$book->id)->where('status',1)->orderBy('id', 'desc')->first(); 

     if($parent){ 
      $parent_id  = $parent->id; 
      $parent_number = $parent->number; 
      $status   = 0; //Define the status of the created page 
     } 
     else{ 
      //If it's the first page of the book 
      $parent_id  = 0; 
      $parent_number = 0; 
      $status   = 1; //if there's no parent page, the new page is the first - auto validated - page of the book. 
      if($book->user_id != Auth::user()->id) { 
       return Response::json(
        array(
         'metadata' => array(
          'error'  => true, 
          'message' => 'You have to be the author of a book to write the first page.' 
         ) 

        ), 
        403 
       ); 
      } 
     } 

     $page    = new Page; 
     $page->content  = $content; 
     $page->book_id  = $book->id; 
     $page->parent_id = $parent_id; 
     $page->number  = $parent_number + 1; 
     $page->user_id  = Auth::user()->id; 
     $page->status  = $status; 
     $page->save(); 

     $stored  = $page->toArray(); 
     $metadata = array(
      'metadata' => array(
       'error' => false 
      ) 
     ); 

     return Response::json(
       array_merge($stored,$metadata), 
       201 
      ); 
    } 
} 

Всякий раз, когда кто-то создает книгу, он должен написать по крайней мере, его первой странице. Это результат в форме с заголовком, описанием и контентом.

я отправить POST в [...]/книгах с моим вводом названием и описанием

Если Success => Я получаю книгу ID, и отправить его с содержанием ввода в [...]/страницы.

Вот мои проблемы:

  • Кто-то может отправить почту на [...]/книги и хранить новую книгу, без страницы
  • Я хочу, чтобы решить эту проблему в более «успокоительный путь», что означает отсутствие «хак решения», как отправку содержания в/книги и сделать проверку страницы в BookController
  • Кроме того, даже если бы я выбрал хак путь, мой API еще не безопасно: я могу остановить второй запрос (на/pages), который нужно отправить.

Как справиться с этим созависимость?

+0

Вы можете добавить все содержимое в одну форму для книги и страницы и сохранить контент одновременно с одного контроллера или просто создать страницу по умолчанию, когда кто-то создает книгу, а затем позволяет редактировать страницу. –

ответ

2

1-й

Ваших контроллеров делают слишком много, они не должны ничего знать о вашей бизнес-логике это то, что должно обращаться по конкретным классам (модели, репозитории, логика домена классов).

Создать несколько классов справиться с этой логикой, отправить вход в них и сделать это. Назовите их, что вам нужно, используя Laravel, это здорово, потому что вы можете делать все, что хотите, с помощью своего кода.

второй

Если различные ограничения данных, чтобы быть приведено в исполнение, вы можете:

Обрабатывать их на тот же запрос

Зависит от вашего интерфейса, если у вас есть все, что нужно на на одной странице вы просто отправляете данные и обрабатываете их в репозитории, который имеет доступ ко всем вашим моделям.

Пример, который может использоваться для обоих может быть:

Хранилище книг с помощью Dependency Injection, что означает, что книга и страница будет автоматически инстанцирован по Laravel:

class BookRepository { 

    __construct(Book $book, Page $page) 
    { 
     $this->book = $book; 
     $this->page = $page; 
    } 

    public function store($input) 
    { 
     if (! $this->book->validate($input) || !$this->page->validate($input)) 
     { 
      return 'error'; 
     } 

     $book->create(input); 
     $page->create($input); 
    } 

} 

базовая модель с Ваша проверка:

class Book extends BaseModel { 

    public function validate($input) 
    { 
     /// validate here and return 
    } 

} 

Ваши модели и правила для каждого:

class Book extends BaseModel { 

    $book_rules = array(
     'title'   => 'required|min:3', 
     'description' => 'required|min:30' 
    ); 


} 

class Page extends BaseModel { 

    $page_rules = array(
     'content'  => 'required|between:300,350', 
     'book_id'  => 'required|exists:books,id' 
    ); 


} 

А затем создать свой вид, имеющий книгу данные и информацию страницы, и который будет POST в BookController @ магазине:

class BookController extends Controller { 

    public function __controller(BookRepository $book_repository) 
    { 
     $this->book_repository = $book_repository; 
    } 

    public function store() 
    { 
     if (! $this->book_repository->store($input)) 
     { 
      return Redirect::back() 
         ->withErrors(
             $this->book_repository 
             ->validation 
             ->messages() 
             ->all() 
            ); 
     } 

     return Redirect::to('success'); 
    } 

} 

Опять мы используем Dependency Injection. $ book_repository будет автоматически создаваться. Поэтому вашему контроллеру не нужно знать, что такое Книга или страница, просто нужно получить запрос и передать в репозиторий, который позаботится обо всем.

Это еще не все, но это начало.

Обрабатывать их по разным запросам

Это обычно. Пользователь отправляет запрос, проверяет и сохраняет данные. Пользователь отправляет второй запрос, приложение проверяет все и отправляет обратно ошибки, если это необходимо.

Обрабатывать их в фоновом режиме

Это разумный способ сделать это. Ваше приложение получит все данные в одном или нескольких запросах, сохранит их, проверит их с помощью рабочего места очереди и отправит электронным письмам пользователю, сообщив ему, что есть некоторые данные, которые необходимо заполнить. Книги без страниц могут быть удалены через некоторое время. Вы не рискуете иметь плохие данные, и ваш пользователь будет знать, чего не хватает, как только вы это сделаете.

+0

Спасибо за ваш ответ, у меня есть несколько вопросов: 1) Можете ли вы дать мне пример о том, как правильно обращаться? Я думал, что было нормально отправлять вход в restFUL API :) 2) Каким должен быть правильный restFUL URL для всех этих ответов? Спасибо за ваше время –

+0

Я не думаю, что смогу создать код для всех из них, но они похожи, вам просто нужно решить, что для вас лучше, и не забывайте уничтожить всю логику с вашего контроллера , –

+0

Большое спасибо за ваше редактирование. Кажется, лучше сделать это по-своему. Возможно, я ошибался во всех учебниках по API с Laravel, чем ограничивал логику приложения внутри контроллера и использовал только модель в качестве красноречивого ORM :) Еще раз спасибо –

Смежные вопросы