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:
$ 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? TodoRepository
? 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:
$ 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
:
src/controllers/todo-list-todo.controller.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:
src/controllers/todo-list-todo.controller.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:
src/controllers/todo-list-todo.controller.ts
import {repository, Filter, Where} from '@loopback/repository';
import {TodoListRepository} from '../repositories';
import {post, get, patch, del, 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);
}
@get('/todo-lists/{id}/todos')
async find(
@param.path.number('id') id: number,
@param.query.string('filter') filter?: Filter,
) {
return await this.todoListRepo.todos(id).find(filter);
}
@patch('/todo-lists/{id}/todos')
async patch(
@param.path.number('id') id: number,
@requestBody() todo: Partial<Todo>,
@param.query.string('where') where?: Where,
) {
return await this.todoListRepo.todos(id).patch(todo, where);
}
@del('/todo-lists/{id}/todos')
async delete(
@param.path.number('id') id: number,
@param.query.string('where') where?: Where,
) {
return await this.todoListRepo.todos(id).delete(where);
}
}
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.
$ 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 previousPOST
request and a body for a todo. Notice that response body you get back contains propertytodoListId
with the ID from before.GET /todos/{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