Skip to content

Instantly share code, notes, and snippets.

@joesepi
Last active November 10, 2019 23:56
Show Gist options
  • Save joesepi/99defb0d26679a683eca7c412d2ab988 to your computer and use it in GitHub Desktop.
Save joesepi/99defb0d26679a683eca7c412d2ab988 to your computer and use it in GitHub Desktop.
Create REST APIs in minutes with LoopBack 4

LoopBack is a Node.js API framework that enables you to create APIs quickly that interact with backend resources like databases and services.

LoopBack 4, the next generation of LoopBack, includes:

  • A brand new core rewritten in TypeScript that makes this framework simpler to use and easier to extend than ever
  • Support for OpenAPI for comprehensive bottom-up and top-down REST API experience
  • Enablement of instant GraphQL endpoints from REST APIs

In this lab, you will create a todo-list application that tracks to-do items using an in-memory database. You will experience how you can create REST APIs with just 5 steps:

  1. Scaffold a LoopBack 4 application
  2. Create the to-do model
  3. Define the datasource where the data is stored
  4. Add a repository to bind the model and datasource
  5. Add a controller to expose REST APIs

Set up

Two prerequisites are Node.js and the LoopBack 4 CLI, both of which are already installed on this machine.

Scaffold your to-do list application

To generate your application using the toolkit, run the lb4 app command and fill out the on-screen prompts:

$ lb4 app
? Project name: todo-list
? Project description: A todo list API made with LoopBack 4.
? Project root directory: (todo-list)
? Application class name: (TodoListApplication)
? Select features to enable in the project:
❯◉ Enable eslint: add a linter with pre-configured lint rules
 ◉ Enable prettier: install prettier to format code conforming to rules
 ◉ Enable mocha: install mocha to run tests
 ◉ Enable loopbackBuild: use @loopback/build helpers (e.g. lb-eslint)
 ◉ Enable vscode: add VSCode config files
 ◉ Enable docker: include Dockerfile and .dockerignore
 ◉ Enable repositories: include repository imports and RepositoryMixin
 ◉ Enable services: include service-proxy imports and ServiceMixin
 # npm will install dependencies now
 Application todo-list was created in todo-list.

For this tutorial, when prompted with the options for enabling certain project features (loopback’s build, eslint, mocha, etc.), leave them all enabled.

Folder structure

After your application is generated, you will have a folder structure similar to the following:

src/
  __tests__/
    acceptance/
      home-page.acceptance.ts
      ping.controller.acceptance.ts
      test-helper.ts
    README.md
  controllers/
    index.ts
    ping.controller.ts
    README.md
  datasources/
    README.md
  models/
    README.md
  repositories/
    README.md
  application.ts
  index.ts
  migrate.ts
  sequence.ts
public/
  index.html
node_modules/
  ***
LICENSE
README.md
DEVELOPING.md
index.js
index.ts
package.json
tsconfig.json
tsconfig.tsbuildinfo

Create the to-do model

In this section, you will use the LoopBack CLI to create a to-do model. To create the to-do list application, we need to create a to-do model that represents instances of a task on our to-do list. A model describes business domain objects and defines a list of properties with name, type, and other constraints.

In our application, the to-do model serves both as a data transfer object (DTO) for representing incoming to-do items (or instances) on requests, as well as our data structure for use with loopback-datasource-juggler.

The purpose of a to-do list is to track tasks. So, your application needs to let you label and differentiate between unique tasks, add extra information to describe those tasks, and finally, provide a way of tracking whether or not they’re complete.

The to-do model has the following properties:

  • id: a unique id
  • title: a title
  • desc: a description that details the specific task to be accomplished
  • isComplete: a boolean flag for whether or not we’ve completed the task

We can use the lb4 model command and answer the prompts to generate the model for us. Note that you should run this command within the newly created todo-list directory. Press return with an empty property name to generate the model.

Follow the in the CLI prompts:

$ lb4 model
? Model class name: todo
? Please select the model base class: Entity (A persisted model with an ID)
? Allow additional (free-form) properties? No

Let's add a property to Todo
Enter an empty property name when done

? Enter the property name: id
? Property type: number
? Is id the ID property? Yes
? Is it required?: No
? Is id generated automatically? Yes
? Default value [leave blank for none]:

Let's add another property to Todo
Enter an empty property name when done

? Enter the property name: title
? Property type: string
? Is it required?: Yes
? Default value [leave blank for none]:

Let's add another property to Todo
Enter an empty property name when done

? Enter the property name: desc
? Property type: string
? Is it required?: No
? Default value [leave blank for none]:

Let's add another property to Todo
Enter an empty property name when done

? Enter the property name: isComplete
? Property type: boolean
? Is it required?: No
? Default value [leave blank for none]:

Let's add another property to Todo
Enter an empty property name when done

? Enter the property name:

   create src/models/todo.model.ts
   update src/models/index.ts

Model todo was created in src/models/

And that's it! You created the to-do model and described it in TypeScript in src/models/todo.model.ts. The update in index.ts adds the todo.model.ts to the list of exported models.

Add a datasource

LoopBack uses datasources to connect to various sources of data, such as databases, APIs, message queues, and more. A datasource in LoopBack 4 is a named configuration for a connector instance that represents data in an external system. The connector is used by legacy-juggler-bridge to power LoopBack 4 repositories for data operations. For more information about datasources in LoopBack, see Datasources.

From inside the project folder, run the lb4 datasource command to create a datasource. For the sake of simplicity, we use the in-memory database which persists the data in a local file system.

$ lb4 datasource
? Datasource name: db
? Select the connector for db: In-memory db (supported by StrongLoop)
? window.localStorage key to use for persistence (browser only):
? Full path to file for persistence (server only): ./data/db.json

  create src/datasources/db.datasource.json
  create src/datasources/db.datasource.ts
  update src/datasources/index.ts

Datasource db was created in src/datasources/

Since we have specified the file ./data/db.json to persist the data for the in-memory connector, let's create the directory and file from the project's root and add in the values shown below using your favorite editor (vim for instance).

$ mkdir data
$ touch data/db.json

In the data/db.json file, copy and paste the JSON below to give your model some data:

{
  "ids": {
    "Todo": 5
  },
  "models": {
    "Todo": {
      "1": "{\"title\":\"Take over the galaxy\",\"desc\":\"MWAHAHAHAHAHAHAHAHAHAHAHAHAMWAHAHAHAHAHAHAHAHAHAHAHAHA\",\"id\":1}",
      "2": "{\"title\":\"destroy alderaan\",\"desc\":\"Make sure there are no survivors left!\",\"id\":2}",
      "3": "{\"title\":\"play space invaders\",\"desc\":\"Become the very best!\",\"id\":3}",
      "4": "{\"title\":\"crush rebel scum\",\"desc\":\"Every.Last.One.\",\"id\":4}"
    }
  }
}

Now that you’ve added the datasource, let's move on to add a repository for the datasource.

Add a repository

A repository represents a specialized service interface that provides strong-typed data access (for example, CRUD) operations of a domain model against the underlying database or service. Learn more about Repositories in the LoopBack documentation.

From inside the project folder, run the lb4 repository command to create a repository for your to-do model using the db datasource from the previous step. The db datasource shows up by its class name DbDataSource from the list of available datasources.

$ lb4 repository
? Please select the datasource DbDatasource
? Select the model(s) you want to generate a repository Todo
? Please select the repository base class DefaultCrudRepository (Legacy juggler bridge)
   create src/repositories/todo.repository.ts
   update src/repositories/index.ts

Repository TodoRepository was created in src/repositories/

The src/repositories/index.ts file makes exporting artifacts central and also easier to import.

The newly created todo.repository.ts class has the necessary connections that are needed to perform CRUD operations for our to-do model. It leverages the to-do model definition and 'db' datasource configuration and retrieves the datasource using Dependency Injection.

Next, we'll need to build a controller to handle our incoming requests.

Add a controller

In LoopBack 4, controllers handle the request-response lifecycle for your API. Each function on a controller can be addressed individually to handle an incoming request (like a POST request to /todos), to perform business logic and to return a response. In this respect, controllers are the regions where most of your business logic will live!

For more information about Controllers, see the LoopBack documentation.

You can create a REST controller using the CLI as follows:

$ lb4 controller
? Controller class name: todo
Controller Todo will be created in src/controllers/todo.controller.ts

? 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? Todo
? What is the name of your CRUD repository? TodoRepository
? What is the name of ID property? id
? What is the type of your ID? number
? Is the id omitted when creating a new instance? Yes
? What is the base HTTP path name of the CRUD operations? /todos
   create src/controllers/todo.controller.ts
   update src/controllers/index.ts

Controller Todo was created in src/controllers/

The application is ready to run. Before that, let's review the code in TodoController located in src/controllers/todo.controller.ts. This example uses two new decorators to provide LoopBack with metadata about the route, verb, and format of the incoming request body:

  • @post('/todos') creates metadata for @loopback/rest so that it can redirect requests to this function when the path and verb match.
  • @requestBody() associates the OpenAPI schema for a Todo with the body of the request so that LoopBack can validate the format of an incoming request.
  • We’ve also added our own validation logic to ensure that a user will receive an error if they fail to provide a title property with their POST request.

Now that we’ve connected the controller, our last step is to tie it all into the application!

Put it all together

Let’s try out our application! First, you’ll want to start the app.

$ npm start
Server is running at http://127.0.0.1:3000
Try http://127.0.0.1:3000/ping

Next, you can use the API Explorer to browse your API and make requests!

Here are some requests you can try:

  • POST /todos with a body of { "title": "buy milk" }.
  • GET /todos/{id} using the ID you received from your POST, and see if you get your Todo object back.
  • PATCH /todos/{id} using the same ID with a body of { "desc": "need milk for cereal" }.
  • GET /todos/{id} using the ID from the previous steps to see that your changes are persisted.

That’s it! You’ve just created your first LoopBack 4 application.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment