UNPKG

@loopback/docs

Version:
224 lines (185 loc) 6.79 kB
--- lang: en title: "Add TodoList and TodoList's Todo Controller" keywords: LoopBack 4.0, LoopBack 4 sidebar: lb4_sidebar permalink: /doc/en/lb4/todo-list-tutorial-controller.html summary: LoopBack 4 TodoList Application Tutorial - Add TodoList and TodoList's Todo Controller --- ### Controllers with related models Defining business logic to handle requests to related models isn't too different from handling requests for standalone models. We'll create controllers to handle requests for todo-lists and todo items under a todo-list. ### Create TodoList controller Run the CLI command for creating a RESTful CRUD controller for our `TodoList` routes with the following inputs: ```sh $ lb4 controller ? Controller class name: TodoList ? What kind of controller would you like to generate? REST Controller with CRUD functions ? What is the name of the model to use with this CRUD repository? TodoList ? What is the name of your CRUD repository? TodoListRepository ? What is the type of your ID? number ? What is the base HTTP path name of the CRUD operations? /todo-lists create src/controllers/todo-list.controller.ts update src/controllers/index.ts Controller TodoList was created in src/controllers/ ``` And voilà! We now have a set of basic APIs for todo-lists, just like that! ### Create TodoList's Todo controller For the controller handling `Todos` of a `TodoList`, we'll start with an empty controller: ```sh $ lb4 controller ? Controller class name: TodoListTodo ? What kind of controller would you like to generate? Empty Controller create src/controllers/todo-list-todo.controller.ts update src/controllers/index.ts Controller TodoListTodo was created in src/controllers/ ``` Let's add in an injection for our `TodoListRepository`: {% include code-caption.html content="src/controllers/todo-list-todo.controller.ts" %} ```ts import {repository} from '@loopback/repository'; import {TodoListRepository} from '../repositories'; export class TodoListTodoController { constructor( @repository(TodoListRepository) protected todoListRepo: TodoListRepository, ) {} } ``` We're now ready to add in some routes for our todo requests. To call the CRUD methods on a todo-list's todo items, we'll first need to create a constrained `TodoRepository`. We can achieve this by using our repository instance's `todos` factory function that we defined earlier in `TodoListRepository`. The `POST` request from `/todo-lists/{id}/todos` should look similar to the following request: {% include code-caption.html content="src/controllers/todo-list-todo.controller.ts" %} ```ts import {repository} from '@loopback/repository'; import {TodoListRepository} from '../repositories'; import {post, param, requestBody} from '@loopback/rest'; import {Todo} from '../models'; export class TodoListTodoController { constructor( @repository(TodoListRepository) protected todoListRepo: TodoListRepository, ) {} @post('/todo-lists/{id}/todos') async create(@param.path.number('id') id: number, @requestBody() todo: Todo) { return await this.todoListRepo.todos(id).create(todo); } } ``` Using our constraining factory as we did with the `POST` request, we'll define the controller methods for the rest of the HTTP verbs for the route. The completed controller should look as follows: {% include code-caption.html content="src/controllers/todo-list-todo.controller.ts" %} ```ts import { Count, CountSchema, Filter, repository, Where, } from '@loopback/repository'; import { del, get, getWhereSchemaFor, param, patch, post, requestBody, } from '@loopback/rest'; import {Todo} from '../models'; import {TodoListRepository} from '../repositories'; export class TodoListTodoController { constructor( @repository(TodoListRepository) protected todoListRepo: TodoListRepository, ) {} @post('/todo-lists/{id}/todos', { responses: { '200': { description: 'TodoList.Todo model instance', content: {'application/json': {schema: {'x-ts-type': Todo}}}, }, }, }) async create( @param.path.number('id') id: number, @requestBody() todo: Todo, ): Promise<Todo> { return await this.todoListRepo.todos(id).create(todo); } @get('/todo-lists/{id}/todos', { responses: { '200': { description: "Array of Todo's belonging to TodoList", content: { 'application/json': { schema: {type: 'array', items: {'x-ts-type': Todo}}, }, }, }, }, }) async find( @param.path.number('id') id: number, @param.query.object('filter') filter?: Filter, ): Promise<Todo[]> { return await this.todoListRepo.todos(id).find(filter); } @patch('/todo-lists/{id}/todos', { responses: { '200': { description: 'TodoList.Todo PATCH success count', content: {'application/json': {schema: CountSchema}}, }, }, }) async patch( @param.path.number('id') id: number, @requestBody() todo: Partial<Todo>, @param.query.object('where', getWhereSchemaFor(Todo)) where?: Where, ): Promise<Count> { return await this.todoListRepo.todos(id).patch(todo, where); } @del('/todo-lists/{id}/todos', { responses: { '200': { description: 'TodoList.Todo DELETE success count', content: {'application/json': {schema: CountSchema}}, }, }, }) async delete( @param.path.number('id') id: number, @param.query.object('where', getWhereSchemaFor(Todo)) where?: Where, ): Promise<Count> { return await this.todoListRepo.todos(id).delete(where); } } ``` Check out our todo-list example to see the full source code generated for TodoListTodo controller: [src/controllers/todo-list-todo.controller.ts](https://github.com/strongloop/loopback-next/blob/master/examples/todo-list/src/controllers/todo-list-todo.controller.ts) ### Try it out With the controllers complete, your application is ready to start up again! `@loopback/boot` should wire up everything for us when we start the application, so there's nothing else we need to do before we try out our new routes. ```sh $ npm start Server is running at http://127.0.0.1:3000 ``` Here are some new requests you can try out: - `POST /todo-lists` with a body of `{ "title": "grocery list" }`. - `POST /todo-lists/{id}/todos` using the ID you got back from the previous `POST` request and a body for a todo. Notice that response body you get back contains property `todoListId` with the ID from before. - `GET /todo-lists/{id}/todos` and see if you get the todo you created from before. And there you have it! You now have the power to define APIs for related models! ### Navigation Previous step: [Add TodoList repository](todo-list-tutorial-repository.md)