Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Adam Miedema
Adam Miedema

Posted on • Edited on

     

Creating a REST API using Adonis v5

In this multi-part tutorial, we'll create and deploy a multi-server architecture web application.

Part 1:Creating a front-end using NuxtJS and TailwindCSS
Part 2:Setting up Adonis v5 with PostgreSQL
Part 3: Creating a REST API using Adonis v5
Part 4:Connecting Nuxt front-end to Adonis 5 API
Part 5:Deploying a multi-server app with Cleavr

Frameworks and tools used

Part 3 - Creating a REST API using Adonis v5 and PostgreSQL

Let's dig a little deeper into Adonis and create a Rest API. For this, we'll need to create a data model, routes, and controller. We'll also set up a database table migration and create a seeder to seed the database with.

Set up RESTful API routes

Adonis makes the standard CRUD operations easily available for you so that you don't have to define everything yourself.

UsingRoute.resource() will automatically set up all of the typical CRUD routes for you. Let's add in the following route:

Route.resource('movies','MoviesController').only(['index','show']).apiOnly()
Enter fullscreen modeExit fullscreen mode

What this does is set up our CRUD routes for/movies and assigns them to refer to theMoviesController, in which we'll define later on.

However, since I am making a simple app and am only interested in fetching either all of the movies or a single movie, I'll use.only() to only include theindex andshow routes.

We'll also add.apiOnly(). Otherwise,.resource() will create form routes; which, we don't need.

Run the following command in your terminal to verify that only theindex andshow routes are created.

node ace list:routes
Enter fullscreen modeExit fullscreen mode

Make a data model class

To create a new model, use the following command:

node ace make:model Movie
Enter fullscreen modeExit fullscreen mode

This operation creates a new file at/app/Models/Movie.ts and gives us a head start with creating the model.

Recalling the data points that we need for our front-end, we'll define the model class for Movies as follows:

import{DateTime}from'luxon'import{BaseModel,column}from'@ioc:Adonis/Lucid/Orm'exportdefaultclassMovieextendsBaseModel{@column({isPrimary:true})publicid:number@column()publictitle:String@column()publicposterImage:String@column()publicreleaseYear:Number@column()publictopBilled:String@column()publicgenres:String@column()publicmovieDescription:String@column()publicmovieReview:String@column.dateTime({autoCreate:true})publiccreatedAt:DateTime@column.dateTime({autoCreate:true,autoUpdate:true})publicupdatedAt:DateTime}
Enter fullscreen modeExit fullscreen mode

Make a data migration and migrate the database

Run the following command to create a new migration:

node ace make:migration movies
Enter fullscreen modeExit fullscreen mode

This will create a file located at/database/migrations/<timestamp>_movies.ts.

Let's navigate to the migration file and add in the table columns.

importBaseSchemafrom'@ioc:Adonis/Lucid/Schema'exportdefaultclassMoviesextendsBaseSchema{protectedtableName='movies'publicasyncup(){this.schema.createTable(this.tableName,(table)=>{table.increments('id')table.timestamps(true)table.string('title').notNullable()table.string('poster_image').notNullable()table.string('release_year').notNullable()table.string('top_billed').notNullable()table.string('genres').notNullable()table.string('movie_description').notNullable()table.string('movie_review').notNullable()})}publicasyncdown(){this.schema.dropTable(this.tableName)}}
Enter fullscreen modeExit fullscreen mode

Time to migrate the database by running the following command:

node ace migration:run
Enter fullscreen modeExit fullscreen mode

Let's double check our database to see if the table migrated successfully.

I like to useTablePlus to manage my databases; so, I'll open that up to check that a migration row was added to theadonis_schema table and that my movies table and it's columns were properly migrated. And... They look good! 🎉

Make a seeder and seed the database

We'll now set up a seeder to seed our database with the example movies that we identified while creating the front-end - Children of Men, The Terminator, and The Sisterhood of the Traveling Pants.

node ace make:seeder Movies
Enter fullscreen modeExit fullscreen mode

The above command will output a new seeder file atdatabases/seeders/Movies.ts.

Let's import theMovie data model and then add JSON for the 3 sets of movie details we want to seed our database with.

importBaseSeederfrom'@ioc:Adonis/Lucid/Seeder'importMoviefrom"App/Models/Movie";exportdefaultclassMovieSeederextendsBaseSeeder{publicasyncrun(){awaitMovie.createMany([{title:'Children of Men',posterImage:'https://m.media-amazon.com/images/M/MV5BMTQ5NTI2NTI4NF5BMl5BanBnXkFtZTcwNjk2NDA2OQ@@._V1_.jpg',releaseYear:2006,topBilled:'Clive Owen, Julianne Moore, Michael Cane',genres:'Adventure, Drama, Sci-Fi',movieDescription:'In 2027, in a chaotic world in which women have become somehow infertile, a former activist agrees to help transport a miraculously pregnant woman to a sanctuary at sea.',movieReview:'The movie is pretty good. It\'s known for long, seemingly un-cut sequences. It\'s better than Gravity. It\'s not as good as Galaxy Quest. You should watch it. I mean, what else are you doing?'},{title:'The Terminator',posterImage:'https://m.media-amazon.com/images/M/MV5BYTViNzMxZjEtZGEwNy00MDNiLWIzNGQtZDY2MjQ1OWViZjFmXkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_SY1000_CR0,0,666,1000_AL_.jpg',releaseYear:1984,topBilled:'Arnold Schwarzenegger, Michael Biehn, Linda Hamilton',genres:'Action, Sci-Fi',movieDescription:'A human soldier is sent from 2029 to 1984 to stop an almost indestructible cyborg killing machine, sent from the same year, which has been programmed to execute a young woman whose unborn son is the key to humanity\'s future salvation.',movieReview:'Like most movies that turn into a series, the 2nd one is wayyyyy better. In this movie, Schwarzenegger is the bad guy. The great thing for him, is that he\'s not required to act and just plays his normal self. Hollywood. A wonderland!'},{title:'The Sisterhood of the Traveling Pants',posterImage:'https://m.media-amazon.com/images/M/MV5BNmRjYWE3OTQtYzEwOC00OWM4LTk3MzktZTUyZTgzNjY4NDc0L2ltYWdlL2ltYWdlXkEyXkFqcGdeQXVyMTQxNzMzNDI@._V1_UX182_CR0,0,182,268_AL_.jpg',releaseYear:2005,topBilled:'Amber Tamblyn, Alexis Bledel, America Ferrera, Blake Lively',genres:'Comedy, Drama, Romance',movieDescription:'Four best girlfriends hatch a plan to stay connected with one another as their lives start off in different directions: they pass around a pair of secondhand jeans that fits each of their bodies perfectly.',movieReview:'This movie is about the greatest miracle the world has seen. The pants fit them all! Furthermore, the pants travel all over the world. They\'re like a traveling gnome. But, more fun to watch!'},])}}
Enter fullscreen modeExit fullscreen mode

Now, to seed the database, run:

node ace db:seed
Enter fullscreen modeExit fullscreen mode

At this step, I was asked to installluxon prior to being able to successfully run the seed command. You can install this package running the following:

npm install --save luxon
Enter fullscreen modeExit fullscreen mode

Once you have successfully ran the seed command, go back to your database management client and verify that the data was correctly seeded.

Make a controller class

Time to create the controller class!

node ace make:controller MoviesController
Enter fullscreen modeExit fullscreen mode

This will create a controller file atapp/Controllers/Http/MoviesController.ts.

Head over to the new file and we'll start by adding in the Movie model.

importMoviefrom"App/Models/Movie"
Enter fullscreen modeExit fullscreen mode

Next, we'll add in our index function.

exportdefaultclassMoviesController{publicasyncindex(){constmovies=awaitMovie.all()returnmovies}}
Enter fullscreen modeExit fullscreen mode

The.all() method is a shorthand to query and return everything from the movies table.

We'll use this route for our homepage that displays the list of movies.

Now, for our details page, we only want to return data for a single movie.

Let's add in the following to ourMovieController class:

publicasyncshow({params}){constmovie=awaitMovie.find(params.id)returnmovie}
Enter fullscreen modeExit fullscreen mode

We're passing inparams.id in the.find function to pull the movie id from the request url and then looking up the movie in our database using the returned id.

We now have all routes and controller defined. Time to test the API! 😎

Test the API

To test the API, I'll usePostman; though, you can use your favorite web browser if you do not want to use an API client.

In Postman, I'll make aGet request and add in my local address and append the url with/movies.

This request will trigger theindex router and then return the full list of movies as we defined inMoviesController.

CleanShot 2020-09-20 at 11.11.10@2x

It works!

Now, let's check passing a movie id to verify it only returns data for that movie.

CleanShot 2020-09-20 at 11.11.32@2x

Success! 🔥

We now have our API ready and will update the front-end to dynamically call and place the data from the API inpart 4.


Following along? View Part 2 progress on GitHub athttps://github.com/armgitaar/moviesapi.

Watch the full tutorial series uninterrupted on Youtube.

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Keep moving forward.
  • Joined

More fromAdam Miedema

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp