API Context
JodApp's API are segmented into different contexts of JodApp. We call this API Contexts.
There are two terms we will use together:
- API Context: groups endpoints based on the context/application that is calling them.
- Domain Namespace: groups backend models that represents real-world concepts
Goals
-
Match Frontend Routes
- API Contexts should mirror our frontend routing for developer clarity
-
Optimized for the team
- Use terminology that makes sense for engineers
-
RBAC Alignment
-
API context should clearly indicate who has access
Pragmatic Nesting
- Nest
Domain Namespacewith theAPI Contextto get flexibility between:- what we need to show to users
- how we store data (e.g. core storage models like Org::Companies, Careers::Job )
API Path Format
Format:
/{api-context}/{domain}/{model}/..
Example:
/marketplace/listings/jobs/...
- api-context:
marketplace - domain:
listings - model:
job
It's easy to confuse the paths for frontend web urls while reading this doc. Always read the paths from a backend/resourceful perspective.
API Context
| API Context | API Path | Access | Description |
|---|---|---|---|
| marketplace | /marketplace/.. | public | Public where job seekers look for jobs |
| candidates/careers | /candidates/careers/.. | Identities::User with a Careers::UserProfile | endpoints related to users working Career jobs |
| candidates/gig | /candidates/gig/.. | Identities::User with a Gig::UserProfile | endpoints related to users working Gig Career jobs |
| employers | /employers/.. | Identities::User with a Org::UserProfile | employer portal to manage jobs and job_applications |
| admins | /admins/.. | Identities::AdminUser | internal portal for Jod team members to access the system |
Marketplace
Marketplace refers to endpoints used in the public section of the frontend.
The following is not an exhaustive list. It is meant to illustrate how we nest domain-namespace within the api-namespace.
Marketplace: Listings Domain
| api path | controller | domain model | description |
|---|---|---|---|
/marketplace/listings/jobs | app/controllers/marketplace/jobs_controller.rb | ::Job | list all jobs |
/marketplace/listings/jobs/{slug} | app/controllers/marketplace/jobs_controller.rb | ::Job | show single job |
/marketplace/org/companies | app/controllers/marketplace/org/companies_controller.rb | ::Org::Companies | list all companies |
Exploratory Notes
Consider the API path /marketplace/org/companies.
User Intent: I want to browse all companies in JodApp
GET /marketplace/org/companieswould return an array ofOrg::Companys.
We might need to show a set of attributes that need to be pulled from different models/database tables.
- For example, what's the response time of confirming a
Gig::JobApplication? - That data might be stored in
Org::CompanyStats
We can have a Data Transfer Object (DTO) that pulls all those data together to form a Listing::Org::Company.
- with the
::ListingsDomain Namespace (not API context), we can represent a core domain model (i.e. Org::Company) as another model for read-only (i.e. users browsing)
Think of it like how we implemented ::Job, which was a projection for Careers::Job and Gig::Job.
Listing::Org::Company would be projection of Org::Company for a user in browsing.
Candidates
Web URL: jodapp.com/candidates/...
Candidates are endpoints meant for non-org users.
Identities::Userthat has associatedCareers::UserProfileand/orGig::UserProfile
Since they can apply to two different jobs that have different business process, we will further nest their endpoints with Domain Namespaces.
| api path | description |
|---|---|
/candidates/career/... | endpoints related to the ::Careers domain models (e.g. Careers::UserProfile, Careers::Job, etc.) |
/candidates/gig/.. | endpoints related to the ::Gig domain models (e.g. Gig::UserProfile, Gig::Job etc.) |
Candidates: Career Domain
Web URL: jodapp.com/candidates/careers
Used by Identities::Users with a Careers::UserProfile to update and manage their careers job applications and profile.
| api path | controller | related domain model |
|---|---|---|
/candidates/career/user_profile | /app/controllers/candidates/careers/user_profiles_controller.rb | Careers::UserProfile |
/candidates/career/user_experiences | /app/controllers/candidates/careers/user_experiences_controller.rb | Careers::UserExperience |
/candidates/career/job_applications | /app/controllers/candidates/careers/job_applications_controller.rb | Careers::JobApplication |
Candidates: Gig Domain
Web URL: jodapp.com/candidates/gig
Used by Identities::Users with a Gig::UserProfile to update and manage their gig job applications and profile.
| api path | controller | related domain model |
|---|---|---|
/candidates/gig/user_profile | /app/controllers/candidates/gig/user_profiles_controller.rb | Gig::UserProfile |
/candidates/gig/jobs | /app/controllers/candidates/gig/jobs_controller.rb | Gig::Job |
/candidates/gig/job_applications | /app/controllers/candidates/gig/job_applications_controller.rb | Gig::JobApplication |
Employers
API Context Employers are endpoints meant for Org Users
Identities::Userthat has an associatedOrg::UserProfile
Employers: Org Domain
| api path | controller | related domain model |
|---|---|---|
/employers/org/companies | /app/controllers/employers/org/companies_controller.rb | Org::Companies |
/employers/org/user_profiles | /app/controllers/employers/org/user_profiles_controller.rb | Org::UserProfile |
Employers: Career Domain
| api path | controller | related domain model |
|---|---|---|
/employers/career/jobs | /app/controllers/employers/career/jobs_controller.rb | Careers::Job |
/employers/career/job_applications | /app/controllers/employers/careers/job_application_controller.rb | Careers::JobApplication |
Employers: Gig Domain
| api path | controller | related domain model |
|---|---|---|
/employers/gig/jobs | /app/controllers/employers/gig/jobs_controller.rb | Gig::Job |
/employers/gig/job_applications | /app/controllers/employers/gig/job_application_controller.rb | Gig::JobApplication |