Consuming Laravel REST API in Expo / React Native: A Step-by-Step Guide

Consuming Laravel REST API in Expo / React Native: A Step-by-Step Guide cover

In this guide, we’ll walk through how to consume a Laravel REST API in an Expo/React Native application. We’ll create a simple Laravel API that returns a list of Pokémon, and then we’ll display that list in a React Native app using NativeWind for styling. By the end of this tutorial, you’ll have a working example of how to fetch data from a Laravel backend and render it in a mobile app.

Prerequisites

Before we start, make sure you have the following installed:

  1. Laravel: A PHP framework for building the API.
  2. Expo CLI: For setting up and running the React Native app.
  3. Node.js: Required for running the React Native app.
  4. Composer: For managing Laravel dependencies.
  5. NativeWind: A utility-first CSS framework for React Native.
  6. Guzzle HTTP Client: For making HTTP requests in Laravel to fetch Pokémon data from PokéAPI.

Step 1: Set Up the Laravel API

1.0 Create a New Laravel Project

Open your terminal and run the following command to create a new Laravel project:

composer create-project --prefer-dist laravel/laravel pokemon-api

Navigate into the project directory:

cd pokemon-api

1.1 Install Guzzle HTTP Client

Guzzle is a PHP HTTP client that makes it easy to send HTTP requests. Install it via Composer:

composer require guzzlehttp/guzzle

1.2 Create a Pokémon Model and Migration

Generate a model and migration for the Pokémon data:

php artisan make:model Pokemon -m

This command creates a Pokemon model and a migration file in the database/migrations directory.

1.3 Define the Pokémon Table Schema

Open the migration file (e.g., database/migrations/xxxx_xx_xx_create_pokemons_table.php) and define the schema:

public function up()
{
    Schema::create('pokemons', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->string('type');
        $table->string('image_url');
        $table->timestamps();
    });
}

Run the migration to create the table:

php artisan migrate

Open the Pokemon model (app/Models/Pokemon.php) and add the image_url field to the $fillable array:

protected $fillable = ['name', 'type', 'image_url'];

1.4 Seed the Database with Pokémon Data

Create a seeder to populate the pokemons table with sample data:

php artisan make:seeder PokemonSeeder

Open the seeder file (database/seeders/PokemonSeeder.php) and add the following:

use App\Models\Pokemon;
use GuzzleHttp\Client;

public function run()
{
    $client = new Client();
    $pokemonCount = 20; // Number of Pokémon to fetch

    for ($i = 1; $i <= $pokemonCount; $i++) {
        $response = $client->get("https://pokeapi.co/api/v2/pokemon/{$i}");
        $data = json_decode($response->getBody(), true);

        $name = $data['name'];
        $type = $data['types'][0]['type']['name']; // Get the first type
        $imageUrl = $data['sprites']['front_default']; // Get the image URL

        Pokemon::create([
            'name' => ucfirst($name),
            'type' => ucfirst($type),
            'image_url' => $imageUrl,
        ]);
    }
}

Run the seeder:

php artisan db:seed --class=PokemonSeeder

1.5 Create a REST API Endpoint

Open the routes/api.php file and define a route to fetch the Pokémon list. Ensure the `/api/pokemons` route returns the Pokémon data:

use App\Models\Pokemon;

Route::get('/pokemons', function () {
    return Pokemon::all();
});

1.6 Test the API

Start the Laravel development server:

php artisan serve

Visit http://localhost:8000/api/pokemons in your browser or use a tool like Postman to verify that the API returns the Pokémon data in JSON format.

Step 2: Set Up the Expo/React Native App

2.1 Create a New Expo Project

Run the following command to create a new Expo project:

npx create-expo-app@latest pokemon-app

Navigate into the project directory:

cd pokemon-app

2.2 Install Dependencies

Install the required dependencies for NativeWind and React Navigation (optional for navigation):

npm install nativewind
npm install @react-navigation/native @react-navigation/stack
npm install react-native-screens react-native-safe-area-context

2.3 Configure NativeWind

Update your babel.config.js file to include NativeWind:

module.exports = function (api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
    plugins: ['nativewind/babel'],
  };
};

Create a tailwind.config.js file:

module.exports = {
  content: [
    './App.{js,jsx,ts,tsx}',
    './components/**/*.{js,jsx,ts,tsx}',
  ],
  theme: {
    extend: {},
  },
  plugins: [],
};

2.4 Create a Pokémon Card Component

Create a new file components/PokemonCard.js:

import React from 'react';
import { View, Text, Image } from 'react-native';

const PokemonCard = ({ name, type, imageUrl }) => {
  return (
    <View className="bg-white p-4 rounded-lg shadow-md mb-4">
      <Image
        source={{ uri: imageUrl }}
        className="w-full h-40 mb-2 rounded-lg"
        resizeMode="contain"
      />
      <Text className="text-xl font-bold">{name}</Text>
      <Text className="text-gray-600">Type: {type}</Text>
    </View>
  );
};

export default PokemonCard;

2.5 Fetch Data from the Laravel API

Open App.js and replace its content with the following:

import React, { useEffect, useState } from 'react';
import { View, ScrollView, ActivityIndicator } from 'react-native';
import PokemonCard from './components/PokemonCard';

export default function App() {
  const [pokemons, setPokemons] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch('http://localhost:8000/api/pokemons')
      .then((response) => response.json())
      .then((data) => {
        setPokemons(data);
        setLoading(false);
      })
      .catch((error) => {
        console.error(error);
        setLoading(false);
      });
  }, []);

  if (loading) {
    return (
      <View className="flex-1 justify-center items-center">
        <ActivityIndicator size="large" color="#0000ff" />
      </View>
    );
  }

  return (
    <ScrollView className="p-4">
      {pokemons.map((pokemon) => (
        <PokemonCard
          key={pokemon.id}
          name={pokemon.name}
          type={pokemon.type}
          imageUrl={pokemon.image_url}
        />
      ))}
    </ScrollView>
  );
}

2.6 Run the App

Start the Expo development server:

npx expo start

Scan the QR code with the Expo Go app or run it on an emulator to see the Pokémon list displayed as cards. You should now see a list of 20 Pokémon displayed in cards, each with their name, type, and image. The cards are styled using NativeWind, making the UI clean and responsive.

Optional Enhancements

  1. Pagination: Implement pagination in the Laravel API to handle large datasets.
  2. Search: Add a search bar in the React Native app to filter Pokémon by name or type.
  3. Details Screen: Use React Navigation to create a details screen for each Pokémon.

That’s it! You’ve successfully built a Laravel API that fetches Pokémon data from PokéAPI and displays it in a React Native app with images. This setup can be extended further to build a full-fledged Pokémon app.

Happy coding! 🚀

Recent Guides

Hestia Kit Premium

You have to be signed in to favorite this

Share

Hestia Kit Premium

This is Hestia Kit premium component